2016/02/07 - Apache Onami has been retired.

For more information, please explore the Attic.

Mock framework

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:

  • Easy-Mock (org.apache.onami.test.mock.annotation.MockType.EASY_MOCK)
  • Mockito (org.apache.onami.test.mock.annotation.MockType.MOCKITO)

    by default JUnice creates Easy-Mock mock objects.

Choose your favorite mock framework

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
{

}

Mock annotation

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:

PropertyTypeDescription
providedByjava.lang.StringSpecifies 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.
providerClassClassIf present specifies a Class that contains the method providedBy, by defaultproviderClass is setted with filed declared class
reserAfterbooleantrue (default) specifies a boolean value to reset this mock object after any test method.
annotateWithClassSpecifies an annotaion Class that will be used in the Google Guice binder to execute the literal binding.
namedWithStringSpecifies an annotaion String>> that will be used in the <<<Google Guice binder to execute the literal binding.
typeorg.apache.onami.test.annotation.MockObjTypeSpecifies 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);
    }

}

Mock resetAfter

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;

    ...

Mock provider

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;

    ...
}

Mock type

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:

  • EASY_MOCK_NORMAL to create a normal EasyMock object mock (default value)
  • EASY_MOCK_STRICT to create a strict EasyMock object mock
  • EASY_MOCK_NICE to create a nice EasyMock object mock

Replace module

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.

Multiple annotation for same type

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 two or more field are annotated with the same org.apache.onami.test.annotation.Mock and no different org.apache.onami.test.annotation.Mock#annotatedWith parameter are specified for these annotation or,
  • two, or more, equals org.apache.onami.test.annotation.Mock#annotatedWith parameter are specified for the same type field.

    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.