www.mockcentral.org mockcentral on sourceforge.net

the mockcentral server

The getting started and examples sections of this documentation provide an introduction to the general concepts and basics of using the MockCentralServer and the javadoc and source are available for more detailed information, so this page focuses on practical usage issues.

requirements

MockCentralServer requires java version 1.6 or greater and that the following libraries to be on the classpath: commons-beanutils, commons-collections, commons-digester, commons-logging and mockobjects-core. These libraries are freely and widely available from many sources on the web and for convenience they have also been included in the main (non-source) zip and tar.gz distributions.

It is also required that you have a log4j.properties file on your classpath when running your tests.

initialization

The server requires initialization with either an InputStream, File or String for obtaining the xml document used to build fixtures and mock objects. In addition, it can be supplied with a HashMap containing runtime variables for use in tests and/or a boolean value indicating whether proxies should be bound in a NamingContext created by the application. The server's init method is thus heavily overloaded to handle all combinations of these parameters. For details, check out the javadoc.

the mockcentral testing context

The MockCentralTestingContext can be used to automatically bind proxies for use by classes that perform JNDI lookups invoked in your tests. It's basically a simple Map-based implementation of the javax.naming.Context interface. The MockCentralServer (if initialized as described above) will create an instance of this class which will be assigned as the default for the InitialContextFactory contained in the system's javax.naming.spi.NamingManager. You can use the server's bindFixtureProxies(String) method to load proxy objects into the context at any point in your test cases.

logging

At INFO level, the MockCentralServer application will log messages for the following events:


At DEBUG level, MockCentralServer application will log messages for the following events:


By tracing this logging output you can see exactly what the server is expecting to happen and what calls your tests make relating to bindings and lookups. Here are excerpts from the DEBUG-level output generated when running the test in the jms example:
    INFO [main] (MockCentralServer.java:343) adding runtime variables map: {randomOrderTotal=7}
    INFO [main] (Fixture.java:118) creating Fixture jms_example: defines an OrderTotalProvider mock.
    INFO [main] (Fixture.java:118) creating Fixture totalOrdersMessager_message_sent_ok: defines mocks used for testing message-sending success.
    INFO [main] (Fixture.java:118) creating Fixture totalOrdersMessager_message_sent_failed: defines mocks used for testing message-sending failure.
   DEBUG [main] (MockObjectSetup.java:186) initializing mock object: jms_example.orderTotalProvider (com.xyz.jms.OrderTotalProvider)
   DEBUG [main] (MockObjectSetup.java:302) (orderTotalProvider) added matchAndReturn to method "getTotalOrders" with no params, expected return value set to randomOrderTotal
   DEBUG [main] (MockObjectSetup.java:186) initializing mock object: totalOrdersMessager_message_sent_ok.queue (javax.jms.Queue)
   DEBUG [main] (MockObjectSetup.java:193) added jndi name for mock object: queue/logEntries
            
   ...
            
    INFO [main] (MockCentralServer.java:400) loading fixture totalOrdersMessager_message_sent_ok
   DEBUG [main] (MockCentralTestingContext.java:113) clearing all bindings
   DEBUG [main] (MockCentralTestingContext.java:75) binding object to queue/logEntries
   DEBUG [main] (MockCentralTestingContext.java:75) binding object to ConnectionFactory
   DEBUG [main] (MockCentralTestingContext.java:104) returning object bound to ConnectionFactory
   DEBUG [main] (MockCentralTestingContext.java:104) returning object bound to queue/logEntries
click here to see a sample log4j.properties file for use with MockCentral.

validation and thrown exceptions

For the server to work properly, the configuration files must be well-formed xml and conform to the MockCentral config file DTD. During initialization, the server will validate all data defined for method expectation parameters and expected results to assure that proper values can be created using the specified <valueType>, <valueClassName> and/or <value> xml elements. A MockCentralServerException will be thrown, for example, if the xml indicates that a boolean value type should be created with a value of '3' or a new instance of a class unknown to the server (not on the classpath) should be assigned as a return value. References within method expectations to other mock objects that are not defined in the configuration file will result in a UnknownProxyException being thrown during initialization. Likewise, circular mock object references and fixture imports are tested for. At test execution time, an UnknownProxyException will also be thrown for any unkown proxies you attempt to look up within your test code, say for object creation or verifications.

some strategies for use

Pull initialization code up to test case superclasses. Use test case superclasses or TestSetup classes to perform server initialization and other common setup tasks (like creating references to proxies obtained from the server) that are required by a suite of tests. Sure, this general testing technique is an obvious one, but it's worth mentioning.

Use the 'anyParams' declaration in method expectations to streamline setup. When you need mock object method expectations that will be called repeatedly but with varying parameters and don't require each invocation to return distinct results, add an anyParams xml element to your method expectation (the MockCentralEditor will do this for you with a button-click). This will result in the server creating an AnyConstraintMatcher for the expectation which can handle any input, saving you time and effort.

One config file or many? You can create a single large configuration file for all of your tests (which can facilitate organization and reuse, but may be overkill for running individual tests that don't need every defined mock object and may become unwieldy), or you can create multiple, more finely-grained configuration files (which may be easier to manage and speed the server along, but can require changes to many files if you alter the method signature of one of the interfaces in your domain code). Which approach to use depends on the circumstances, but note that the copy and paste functions available in the MockCentralEditor application can help greatly when you use multiple config files.

Parallel fixtures and fixture importing: Testing how a Method behaves with various input and testing Exception-handling code can require defining multiple mock objects for the different scenarios. Use fixtures to group the mock objects pertaining to each condition you want to test, and abstract common mock objects to a fixture that these can import using the "importFixture" declaration. That way you can easily set up "parallel" fixtures as needed to test your code.