Search code examples
javaunit-testingmockingmockitojmockit

Jmockit: mocking an method on returned interface (Mockito spy() equivalent)


I'm quite new to JMockit and I'm trying to find a way to do something that either I can't do or I don't understand how to do form the documentation. The equivalent is quite easy in Mockito.

I have a number of real concrete classes that return instances referenced by their interface. For example:

final IAmAnInterface interf = 
    someRealClass.createMeAnInterfaceInstance(param1, param2, param3)

I want to mock one of the methods of the implementation of interf out so that it does something specific, but only later on in the test case, e.g. if I was dealing with classes rather than interfaces I'd use:

new Mockup<ConcreteClassOfIAmAnInterface>() {
    @Mock
    int someMethod() throws SomeException {
        return 1+2+3+4+5; // my special value
    }
}

which works fine if I know what someRealClass will return, but if I replace "ConcreteClassOfIAmAnInterface" with "IAmAnInterface" then the method isn't mocked.

If I were to use Mockito I would do something like:

final IAmAnInterface mock = spy(interf);
when(mock.someMethod()).thenReturn(1+2+3+4+5);

Is there a nice way/any way to do this in JMockit?


Solution

  • You were trying to use the "JMockit Mockups" API, which is very different from the typical mocking API.

    Instead, use the more familiar "JMockit Expectations & Verifications" API:

    @Test // note the "mock parameter" below (or declare a mock field)
    public void regularTest(@Mocked final IAmAnInterface mock)
    {
        // Record expectations if/as needed:
        new NonStrictExpectations() {{
            mock.someMethod(); result = 123;
        }};
    
        // Use the mock object in the SUT.
        ...
    
        // Verify expectations if/as needed:
        new Verifications() {{ mock.doSomething(); }};
    }
    
    @Test // this is the equivalent to a Mockito "spy"
    public void testUsingPartialMocking()
    {
       final IAmAnInterface realObject = new SomeImplementation();
    
       new NonStrictExpectations(realObject) {{
          // Record zero or more expectations.
          // Calls to "realObject" *not* recorded here will execute real code.
       }};
    
       // call the SUT
    
       // verify expectations, if any
    }