java - 有没有办法在 Spring MVC 测试中不使用 @MockBean?

标签 java spring spring-boot testing mocking

我正在尝试使用 @WebMvcTest 测试我的 Rest Controller 的 Rest contract,例如:

@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
class MyControllerTest {

我正在测试的方法仅使用 MyFirstService,但在类内部还有另外两个服务(MySecondService 和 MyThirdService)被其他两个方法使用。

问题是@MockBean的使用。测试类在 final 中似乎是这样的:

@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
class MyControllerTest { 

    @MockBean
    private MyFirstService s1; // internal method mocked for the test

    @MockBean
    private MySecondService s2; //never used

    @MockBean
    private MyThirdService s3; //never used

    ...

    @Test
    public void testMethod() [
        // mock s1
        // calls rest controller method
        MvcResult mvcResult = mvc.perform(post("/products")
            .header("Content-Type", "application/json")
            .content(json))
            .andExpect(status().isCreated())
            .andReturn();
    }

}

我认为这个解决方案对于这些注释并不优雅......声明的 s2 和 s3 似乎没有被阅读代码的人使用。注入(inject)到 MyController 中的每个服务都需要使用 @MockBean

所以,我有两个问题:

  1. 有没有办法在 Spring MVC 测试中不使用 @MockBean
  2. 有没有更好的方法来做同样的事情,甚至使用 @MockBean

最佳答案

第一个问题:

Is there a way to not use @MockBean on Spring MVC tests?

@WebMvcTest 允许在 Spring 上下文中仅配置 MVC bean。
作为优势,它隔离了测试并使它们的执行速度更快。
作为缺点,它需要为测试 Controller 的依赖项提供模拟,即使在测试方法中不需要它们。

Spring 文档确认:

41.3.7 Auto-configured Spring MVC tests

Often @WebMvcTest will be limited to a single controller and used in combination with @MockBean to provide mock implementations for required collaborators.

所以在您的情况下,您别无选择。

第二个问题:

Is there a better way to do the same thing, even using @MockBean?

我认为您可以生成更好的代码,方法是将 @MockBean 用于您希望在测试中模拟特定内容的字段,并将 @MockBeans 用于其他 bean 类,具体取决于被测 Controller 。

没有测试,但你可以试试:

@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
@MockBeans({ @MockBean(MySecondService.class), 
             @MockBean(MyThirdService.class) 
           }) // technical mocks for the dependencies resolution

class MyControllerTest { 

    @MockBean
    private MyFirstService s1; 

    @Test
    public void testMethod() [
        // mock s1
        // calls rest controller method
        MvcResult mvcResult = mvc.perform(post("/products")
            .header("Content-Type", "application/json")
            .content(json))
            .andExpect(status().isCreated())
            .andReturn();
    }

}

关于java - 有没有办法在 Spring MVC 测试中不使用 @MockBean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48504036/

相关文章:

spring - 使用 Spring MVC Test 对多部分 POST 请求进行单元测试

spring-boot - 使用 SpringBoot 配置 Spring Cloud Consul

java - 为什么我不应该使用不可变 POJO 而不是 JavaBean?

java - Google NFC API 和 Open NFC API 之间的区别

javascript - 无法找到资源 - Tomcat - Spring - AngularJS

java - Spring Boot - Hibernate - OneToMany - 外键

java - Spring Boot Mongo DB .yml 配置

java - 为什么 PDF 文件需要 LOG4J 和 SLF4J?为什么 .Doc 文件不需要?

java - 使用 Intellij 在 Java 中重构构造函数

spring - BCryptPasswordEncoder - 编码密码看起来不像 BCrypt