java – 使用Spring,@ InjectMock注释的测试目标不使用模拟

我正在尝试对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?

谢谢你 !

解决方法:

我看了你的测试,这应该工作.只需使用模拟bean在控制器上构建MockMvc即可.在此之后,所有的模拟都将在测试中可见.

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.

不要使用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());
    }
}
上一篇:java – Mockito没有正确地将列表作为参数的存根方法


下一篇:java – 模拟bean依赖关系的NoSuchBeanDefinitionException