带有构造函数注入的Spring Boot @WebMvcTest不起作用

问题描述

使用 @WebMvcTest 的构造函数注入有效。被模拟的bean SomeService未初始化。为什么? Mockito 不会独立于Spring Boot创建SomeService吗?

如果我使用 @MockBean ,一切正常,但我想使用构造函数注入。

有什么想法吗?

@WebMvcTest with constructor injection not working

package com.ust.webmini;

@RequiredArgsConstructor
@RestController
public class HelpController {
    @NonNull
    private final SomeService someService;

    @GetMapping("help")
    public String help() {
        return this.someService.getTip();        
    }
}

-------------------------------------------
package com.ust.webmini;

@Service
public class SomeService {
    public String getTip() {
        return "You'd better learn Spring!";
    }
}
-------------------------------------------

@WebMvcTest(HelpController.class)
public class WebMockTest {

    @Autowired
    private MockMvc mockMvc;
    
/* if we use this instead of the 2 lines below,the test will work!
    @MockBean 
    private SomeService someService;
*/
    private SomeService someService = Mockito.mock(SomeService.class);
    private HelpController adviceController = new HelpController(someService);

    @Test
    public void test() {
         // do stuff        
    }
}
---------------------------------------
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.ust.webmini.HelpController required a bean of type 'com.ust.webmini.SomeService' that could not be found.


Action:

Consider defining a bean of type 'com.ust.webmini.SomeService' in your configuration.

UnsatisfiedDependencyException: Error creating bean with name 'helpController' [...]
NoSuchBeanDefinitionException: No qualifying bean of type 'com.ust.webmini.SomeService' available: expected at least 1 bean

解决方法

@MockMvcTest旨在提供一种简单的方法来对特定控制器进行单元测试。它不会扫描任何@Service@Component@Repository bean,但是会拾取任何用@SpyBean@MockBean注释的东西。

@MockBean会像Mockito.mock(...)那样创建指定类型的模拟物,但还会将模拟物实例添加到spring应用程序上下文中。然后,Spring将尝试将bean注入您的控制器。因此,春天本质上会执行与您在此处所做的相同的事情:

private SomeService someService = Mockito.mock(SomeService.class);
private HelpController adviceController = new HelpController(someService);

我建议您坚持使用@MockBean方法。另外,如果您需要访问HelpController,只需在测试中将其自动接线即可。

来自docs

使用此批注将禁用完全自动配置,而是仅应用与MVC测试相关的配置(即@ Controller,@ ControllerAdvice,@ JsonComponent,Converter / GenericConverter,Filter,WebMvcConfigurer和HandlerMethodArgumentResolver Bean,而不是@ Component,@ Service或@Repository bean)。

如果您希望加载完整的应用程序配置并使用MockMVC,则应考虑将@SpringBootTest与@AutoConfigureMockMvc结合使用,而不是此注释。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...