8

I'm new to using Mockito and am trying to understand a way to make a unit test of a class that relies on injected dependencies. What I want to do is to create mock objects of the dependencies and make the class that I am testing use those instead of the regular injected dependencies that would be injected by Spring. I have been reading tutorials but am a bit confused on how to do this.

I have one the class I want to test like this:

package org.rd.server.beans;

import org.springframework.beans.factory.annotation.Autowired;

public class TestBean1 {

    @Autowired
    private SubBean1 subBean1;

    private String helloString;

    public String testReturn () {

        subBean1.setSomething("its working");
        String something = subBean1.getSomething();
        helloString = "Hello...... " + something;

        return helloString;
    }

Then I have the class that I want to use as a mock object (rather than the regular SubBean1 class, like below:

package org.rd.server.beans.mock;

public class SubBean1Mock {

    private String something;

    public String getSomething() {
        return something;
    }

    public void setSomething(String something) {
        this.something = something;
    }


}


    }

I just want to try running a simple test like this:

package test.rd.beans;
import org.rd.server.beans.TestBean1;

import junit.framework.*;


public class TestBean1Test extends TestCase
{
    private TestBean1 testBean1;

    public TestBean1Test(String name)
    {
        super(name);
    }

    public void setUp()
    {
        testBean1 = new TestBean1();
        // Somehow inject the mock dependency SubBean1Mock ???

    }

    public void test1() {
        assertEquals(testBean1.testReturn(),"working");
    }
}

I figure there must be some fairly simple way to do this but I can't seem to understand the tutorials as I don't have the context yet to understand everything they are doing / explaining. If anyone could shed some light on this I would appreciate it.

Rick
  • 16,612
  • 34
  • 110
  • 163

3 Answers3

8

If you're using Mockito you create mocks by calling Mockito's static mock method. You can then just pass in the mock to the class you're trying to test. Your setup method would look something like this:

testBean1 = new TestBean1();
SubBean1 subBeanMock = mock(SubBean1.class);
testBean1.setSubBean(subBeanMock);

You can then add the appropriate behavior to your mock objects for whatever you're trying to test with Mockito's static when method, for example:

when(subBeanMock.getSomething()).thenReturn("its working");
5

In Mockito you aren't really going to create new "mock" implementations, but rather you are going to mock out the methods on the interface of the injected dependency by telling Mockito what to return when the method is called.

I wrote a test of a Spring MVC Controller using Mockito and treated it just like any other java class. I was able to mock out the various other Spring beans I had and inject those using Spring's ReflectionTestUtils to pass in the Mockito based values. I wrote about it in my blog back in February. It has the full source for the test class and most of the source from the controller, so it's probably too long to put the contents here.

http://digitaljoel.nerd-herders.com/2011/02/05/mock-testing-spring-mvc-controller/

digitaljoel
  • 26,265
  • 15
  • 89
  • 115
  • Thanks, your answer helps me a lot to understand it in plain English terms :) I think I am on the right track now – Rick Apr 24 '11 at 03:17
  • I'm fairly new to mocking, but it makes otherwise complex tests really nice once you get your head around how it works. I've really liked Mockito and found it very friendly to work with. Good luck with your testing! – digitaljoel Apr 24 '11 at 03:21
  • thanks, great article, I had some issue with getting it to work though but I understand it better now from that, I'm sure its something I did wrong from being new to it but I was able to get Ed's way to work.. Mock testing is definitely something I should be doing more of – Rick Apr 24 '11 at 06:05
  • model view controller controller? ;) – Michael McKenna Oct 26 '18 at 17:07
0

I stumbled on this thread while trying to set up some mocks for a slightly more complicated situation and figured I'd share my results for posterity.

My situation was similar in the fact that I needed to mock dependencies, but I also wanted to mock some of the methods on the class I was testing. This was the solution:

    @MockBean
    DependentService mockDependentService
    
    ControllerToTest controllerToTest

    @BeforeEach
    public void setup() {
       mockDependentService = mock(DependentService.class);
       controllerToTest = mock(ControllerToTest.class);
       ReflectionTestUtils.setField(controllerToTest, "dependantService", mockDependentService);
    }
    
    @Test
    void test() {
        //set up test and other mocks 
        //be sure to implement the below code that will call the real method that you are wanting to test
        when(controllerToTest.methodToTest()).thenCallRealMethod();
        //assertions
    }

Note that "dependantService" needs to match whatever you have named the instance of the service on your controller. If that doesn't match the reflection will not find it and inject the mock for you.

This approach allows all the methods on the controller to be mocked by default, then you can specifically call out which method you want to use the real one. Then use the reflection to set any dependencies needed with the respective mock objects.

Hope this helps someone down the road as it stumped me for a while.