With Spring, @InjectMock annotated test target doesn't use mocks
java, mockito, spring, spring-mvc, unit-testing
Solution
I'm looked into your tests and this should work. Simply build your MockMvc on your controller with mocked beans. After this all mocks will be visible inside test.
A MockMvcBuilder that accepts `@Controller` registrations thus allowing full control over the instantiation and the initialization of controllers and their dependencies similar to plain unit tests, and also making it possible to test one controller at a time.
Don't use Spring Integration test! This is simple unit testing!
Fixed test
@RunWith(MockitoJUnitRunner.class)
public class TestCtrlTests{
@InjectMocks
TestCtrl testCtrl;
@Mock
TestService testService;
protected MockMvc mockMvc;
@Before
public void setup(){
when(testService.getOne("jexiste")).thenReturn(new com.thalesgroup.ito.c2s.mc.portail.test.domain.Test("jexiste",1990));
when(testService.getOne("plaf")).thenReturn(null);
this.mockMvc = standaloneSetup(testCtrl).build();
}
@Test
public void simpleGetAnswer() throws Exception{
assertNotNull(mockMvc);
mockMvc.perform(get("/test")).andExpect(status().isOk());
mockMvc.perform(get("/test/jexiste")).andExpect(status().isOk());
mockMvc.perform(get("/test/plaf")).andExpect(status().isNotFound());
}
}
Problem
I'm trying to unit test a Spring 4.0.0 MVC application. My controller is defined as follow: ``` @Controller @RequestMapping("/test") public class TestCtrl { @Autowired private TestService testService; @Autowired private TestRessourceAssembler testRessourceAssembler; @Autowired private ResponseComposer responseComposer; @RequestMapping(value = "", method = RequestMethod.GET,produces = "application/json") public HttpEntity showAll(Pageable pageable) { Page<Test> patr = testService.getAll(pageable); return responseComposer.composePage(patr,testRessourceAssembler); } @RequestMapping(value = "/{name}", method = RequestMethod.GET) public HttpEntity<TestRessource> show(@PathVariable String name) { Test test = testService.getOne(name); if(test == null){ return new ResponseEntity("Erreur !",HttpStatus.NOT_FOUND); } return responseComposer.compose(test,testRessourceAssembler); } } ``` My controller unit test is as follow: ``` @RunWith(SpringJUnit4ClassRunner.class) @ActiveProfiles("test") @WebAppConfiguration @ContextConfiguration(classes = {ApplicationConfig.class, TestMongoConfig.class, RestConfig.class, WebMvcConfig.class}) public class TestCtrlTests{ @InjectMocks TestCtrl testCtrl; @Mock TestService testService; @Autowired protected WebApplicationContext wac; protected MockMvc mockMvc; @Before public void setup(){ MockitoAnnotations.initMocks(this); when(testService.getOne("jexiste")).thenReturn(new com.thalesgroup.ito.c2s.mc.portail.test.domain.Test("jexiste",1990)); when(testService.getOne("plaf")).thenReturn(null); this.mockMvc = webAppContextSetup(this.wac).build(); } @Test public void simpleGetAnswer() throws Exception{ assertNotNull(mockMvc); mockMvc.perform(get("/test")).andExpect(status().isOk()); mockMvc.perform(get("/test/jexiste")).andExpect(status().isOk()); mockMvc.perform(get("/test/plaf")).andExpect(status().isNotFound()); } } ``` When I'm running the test, the "normal" TestService bean is injected and used (I can see the trace in the log), not the mock. So I read some things on the internet and replaced ``` this.mockMvc = webAppContextSetup(this.wac).build(); ``` with ``` this.mockMvc = standaloneSetup(TestCtrl.class).build(); ``` But, and I knew it would happen, I've no more Spring context when doing this, so my PageableArgumentResolver and my other beans (testRessourceAssembler, responseComposer) aren't injected anymore... So they are Null and happen a NullPointerException. My question is: 1) I'm I designing something wrong ? 2) If not, how can I inject a mock in my controller while keeping other beans from the context ? Thanks to you !