我正在尝试对Spring 4.0.0 MVC应用程序进行单元测试。
我的控制器定义如下:
@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);
}
}
我的控制器单元测试如下:
@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());
}
}
当我运行测试时,注入并使用“普通”TestService bean(我可以在日志中看到跟踪),而不是模拟。
所以我在互联网上阅读了一些内容并替换了
this.mockMvc = webAppContextSetup(this.wac).build();
与
this.mockMvc = standaloneSetup(TestCtrl.class).build();
但是,我知道会发生这种情况,在执行此操作时我没有更多的Spring上下文,因此我的PageableArgumentResolver和我的其他bean(testRessourceAssembler,responseComposer)不再被注入...所以它们是Null并且发生了的NullPointerException。
我的问题是:
1)我是在设计错误的东西?
2)如果没有,我怎样才能在我的控制器中注入模拟,同时保持其他bean不受上下文的影响?
谢谢你!
答案 0 :(得分:5)
我调查了你的测试,这应该有效。只需使用模拟bean在控制器上构建MockMvc即可。在此之后,所有的模拟都将在测试中可见。
接受
@Controller
注册的MockMvcBuilder,从而允许完全控制实例化和控制器及其依赖关系的初始化,类似于普通单元测试,并且还可以测试一个控制器。
不要使用Spring Integration测试!这是简单的单元测试!
@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());
}
}