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

标签 java spring unit-testing spring-mvc mockito

我正在尝试对 Spring 4.0.0 MVC 应用程序进行单元测试。

我的 Controller 定义如下:

@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);
    }
}

我的 Controller 单元测试如下:

@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 被注入(inject)并使用(我可以在日志中看到跟踪),而不是模拟。

于是在网上看了一些东西,替换了

this.mockMvc = webAppContextSetup(this.wac).build();

this.mockMvc = standaloneSetup(TestCtrl.class).build();

但是,我知道它会发生,在执行此操作时我没有更多的 Spring 上下文,所以我的 PageableArgumentResolver 和我的其他 bean(testRessourceAssembler、responseComposer)不再被注入(inject)...所以它们是 Null 并发生空指针异常。

我的问题是:

1) 我是不是设计错了什么?

2) 如果不是,我如何在我的 Controller 中注入(inject)模拟,同时让其他 bean 远离上下文?

谢谢你!

最佳答案

我查看了您的测试,这应该有效。只需使用模拟 bean 在 Controller 上构建 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 - 使用 Spring,@InjectMock 注释测试目标不使用模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21378361/

相关文章:

java web应用程序无法访问linux文件系统

spring - Spring Boot 配置属性 Unresolved 占位符验证

java - Spring Boot 在单元测试时删除@Component

objective-c - STAsert*() 宏中的 Xcode 补全

java - 如何在 GXT 2.2.3 中禁用和启用 EditorGrid 中的单元格

java - 如何解决应用程序中加载单选按钮选择的延迟?

java - 在 Dockerfile 中覆盖继承的 CMD 并不总是有效?

c# - 如何在 C# 单元测试中验证具有特定 NSpecification 参数的方法?

javascript - 使用 Jest 测试 React Native 时如何模拟 LayoutAnimation

java - 构造函数不能应用于给定类型