Apache Onami-Test integrates two Mock frameworks integrated with Google Guice to inject the mocked object into bussines logic classes, simply by annotating a test fild with @org.apache.onami.test.mock.annotation.Mock annotation. All existing bindins will be replaced with mock object declared into your test class.
JUnice supports this kind of mock:
by default JUnice creates Easy-Mock mock objects.
To choose a different mock framework that Apache Onami-Test shuld be used to create your mock object, you should annotate the test classes in this way:
@RunWith( OnamiRunner.class ) @MockFramework( MockType.MOCKITO ) public class SimpleTest { }
org.apache.onami.test.annotation.Mock is a field annotation used by core Runner to instantiate and inject Mock object into a test case class.
org.apache.onami.test.annotation.Mock can be configured with this parameters:
Property | Type | Description |
---|---|---|
providedBy | java.lang.String | Specifies a java.lang.String that indentifies a public static method with return type is equals to the type of the field annotated by this annotation. |
providerClass | Class | If present specifies a Class that contains the method providedBy, by defaultproviderClass is setted with filed declared class |
reserAfter | boolean | true (default) specifies a boolean value to reset this mock object after any test method. |
annotateWith | Class | Specifies an annotaion Class that will be used in the Google Guice binder to execute the literal binding. |
namedWith | String | Specifies an annotaion String>> that will be used in the <<<Google Guice binder to execute the literal binding. |
type | org.apache.onami.test.annotation.MockObjType | Specifies the mock type. |
In the following example HelloWorld class dependencies will be injected with the mocked class created by the Runner:
public class HelloWorld { @Inject private Service service; ... public String sayHalloByService() { return service.go(); } ... }
Then, in the test class:
@RunWith( OnamiRunner.class ) public class SimpleTest { //Create and inject a simple EasyMock Strict mock @org.apache.onami.test.annotation.Mock private Service service; @Inject private HelloWorld helloWorld; @Test public void testMock() { //Stub created mock EasyMock.expect( service.go() ).andReturn( "Ciao" ); EasyMock.replay( providedMock ); assertNotNull( service ); assertEquals( "Ciao", helloWorld.sayHalloByService()); EasyMock.verify(service); } }
Note The runner will reset any mock object after each test method. To indicate that a mock has to be resetted manually, fields must to be annotated in this way:
... @Mock(resetAfter=false) private Service service; ...
The Runner class create a simple mock for each @Mock annotated filed. You should delegate the mock creation to a method in this way:
@RunWith( OnamiRunner.class ) public class SimpleTest { @Mock( providedBy="providerMethod" ) private Service service; public static Service providerMethod() { Service mocked = EasyMock.createNiceMock(Service.class); ... return mockedService; } ... }
It's possible also delegate an external class:
public class ServiceMockProvider { public static Service providerMethod() { Service mocked = EasyMock.createNiceMock( Service.class ); ... return mockedService; } }
@RunWith( OnamiRunner.class ) public class SimpleTest { @Mock( providedBy = "providerMethod", providerClass = ServiceMockProvider.class ) private Service service; ... }
The Runner class create a simple mock for each @Mock annotated filed. It's possible specify witch type of mock that the Runner creates. The possible values are:
Apache Onami-Test core Runner will replace all existing bindings found into modules declared via @org.apache.onami.test.annotation.GuiceModule and @org.apache.onami.test.annotation.GuiceProvidedModules with mocked object annotated with org.apache.onami.test.annotation.Mock
So given google-guice module:
public class ServiceModule extends AbstractModule { @Override protected void configure() { bind( Service.class).to( ServiceImpl.class ).asEagerSingleton(); ... } }
and your implementation
public class ServiceImpl implements Service { public String go() { return "It's real class"; } }
@RunWith( OnamiRunner.class ) @GuiceModules( ServiceModule.class ) public class TestCustomInjectionTest { @Mock private static Service service; @Test public void testOverideModule() throws Exception { assertNotNull( service ); EasyMock.expect( service.go() ).andReturn( "Mocked injected class" ); assertEquals( "Mocked injected class", service.go() ); } }
service instance will be injected with the mocked object.
It's possible annotate multiple types with the org.apache.onami.test.annotation.Mock annotation
The Method GuiceMockModule#configure() creates a binding for each org.apache.onami.test.annotation.Mock found. The binding will be created if and only if there is no types conflict beetween declared org.apache.onami.test.annotation.Mock.
A type conflict is detected
If a conflict is detected the binding will not be created for this conflicted type, and the field will be injected only into the test class. So if necessary you have to create a proper binding for this org.apache.onami.test.annotation.Mock field:
@RunWith( OnamiRunner.class ) public class TestCustomInjectionTest implements Module { public void configure( Binder binder ) { binder.bind( Service.class ).toInstance( serviceOne ); } @Mock private static Service serviceOne; @Mock private Service serviceTwo; @Inject private HelloWorld helloWorld; @Test public void testOverideModule() throws Exception { assertNotNull( serviceOne ); assertNotNull( serviceTwo ); } }
in this case HelloWorld class has a dependency with Service interface. If you don't specify a proper binding Google Guice raises an com.google.inject.ConfigurationExcepion.