Injecting Mockito Mock objects using Spring JavaConfig and @Autowired

integration-testing, java, mockito, spring, spring-java-config

Solution

Moving away from the now unmaintained (as of this writing) Spingockito-annotations and to Mockito, we have a way of doing this very simply:

@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration
public class MyTestClass {

    @Mock MockInterface mockObj;

    // test code
}

If you're using a real object, but would like to mock a dependency within it, for instance testing a service layer with DAO:

@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration
public class MyTestClass {

    @InjectMocks RealService;

    @Mock MockDAO mockDAO;

    // test code
}

Finally, this can also be applied to Spring-boot, but using annotation initialization within `setUp()` until multiple class runners are supported:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyMainSpringBootClass.class)
public class MyTestClass {

    @InjectMocks RealService;

    @Mock MockDAO mockDAO;

    @Before
    public final void setUp() throws Exception{
        MockitoAnnotations.initMocks(this);
    }

    // test code
}

Problem

I'm trying to replace an `@Autowired` object with a Mockito mock object. The usual way of doing this was with xml using Springockito: ``` <mockito:mock id="SomeMock" class="com.package.MockInterface" /> ``` Currently I'm trying to move over to using Spring's JavaConfig to do the job. All of a sudden the Java expressions are a whole lot more verbose than xml: ``` @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class MyTestClass { @Configuration static class Config { @Bean public MockInterface somethingSpecial() { return Mockito.mock(MockInterface.class); } } @Autowired MockInterface mockObj; // test code } ``` I discovered a library called Springockito-annotations, which allows you to do the following: ``` @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader=SpringockitoContextLoader.class) public class MyTestClass { @Autowired @ReplaceWithMock MockInterface mockObj; // test code } ``` Clearly, a whole lot prettier :) The only problem is that this context loader doesn't allow me to use `@Configuration` and JavaConfig for other beans (if I do, Spring complains that there are no candidates that match those autowired fields). Do you guys know of a way to get Spring's JavaConfig and Springockito-annotations to play nice? Alternatively, is there another shorthand for creating mocks? As a nice bonus, using Springockito and xml config, I was able to mock out concrete classes without providing autowiring candidates to its dependencies (if it had any). Is this not possible without xml?

Original source