Java – Using Mockito to stub and execute methods for testing

javajunitmockingmockito

I've asked a couple of jUnit and Mockito oriented questions recently and I'm still really struggling to get the hang of it. The tutorials are all for very simple examples, so I'm struggling to scale up my test cases to work for my classes.

I'm currently trying to write some test cases for a method I have in one of my agents in a webapp. The method interacts with a couple of other methods inside the agent to validate some objects. I just want to test this one method right now.

Here's what I have tried to do:

  1. Create a Mockito object of my agent like so:

    MyProcessingAgent mockMyAgent = Mockito.mock(MyProcessingAgent.class);

  2. Setup stubs(hopefully the right term) using Mockito.when like so:

    Mockito.when(mockMyAgent.otherMethod(Mockito.any(arg1)).thenReturn(requiredReturnArg);

  3. Try executing my method like so:

    List myReturnValue = mockMyAgent.methodThatNeedsTestCase();

I was expecting to things in myReturnValue, but received 0 instead so I tried to debug. When I call the method, it never executes. I have a debug point at the first line in the method that never gets touched.

If I want to execute the code in one method of a class, but force other methods in the class (one's that try to interact with databases in the outside world) to return faked out values. Is this possible with Mockito?

It appears that my current method of approach is not a correct testing style, but I'm not sure how to move forward. Can I mock my class and have one method be executed like normal while other methods are stubbed to return my given values so that I don't have to deal with data access during testing this one method?

Best Answer

You are confusing a Mock with a Spy.

In a mock all methods are stubbed and return "smart return types". This means that calling any method on a mocked class will do nothing unless you specify behaviour.

In a spy the original functionality of the class is still there but you can validate method invocations in a spy and also override method behaviour.

What you want is

MyProcessingAgent mockMyAgent = Mockito.spy(MyProcessingAgent.class);

A quick example:

static class TestClass {

    public String getThing() {
        return "Thing";
    }

    public String getOtherThing() {
        return getThing();
    }
}

public static void main(String[] args) {
    final TestClass testClass = Mockito.spy(new TestClass());
    Mockito.when(testClass.getThing()).thenReturn("Some Other thing");
    System.out.println(testClass.getOtherThing());
}

Output is:

Some Other thing

NB: You should really try to mock the dependencies for the class being tested not the class itself.