【问题标题】:Spring Boot @WebMvcTest with constructor injection not working带有构造函数注入的 Spring Boot @WebMvcTest 不起作用
【发布时间】:2020-08-11 02:43:41
【问题描述】:

@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

【问题讨论】:

    标签: spring-boot unit-testing spring-mvc constructor-injection spring-mvc-test


    【解决方案1】:

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

    @MockBean 将创建一个指定类型的模拟,就像Mockito.mock(...) 一样,但它也会将模拟实例添加到 Spring 应用程序上下文中。然后 Spring 将尝试将 bean 注入到您的控制器中。所以 spring 基本上和你在这里做的事情是一样的:

    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 结合使用,而不是使用此注解。

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 2019-03-10
      相关资源
      最近更新 更多