首页 > 解决方案 > 如何为多个测试类创建一个通用的 MockMvc 类?

问题描述

我正在为许多不同的 Spring 控制器编写端到端测试。现在,我正在尝试编写一个包含 MockMvc 执行方法的通用测试类。我有需要在不同控制器中调用的端点,我不想复制粘贴代码,并且在每个测试类中都有一个 MockMvc 和 ObjectMapper。

方法的几个例子:

public void saveMockDish(DishDto dishDto) throws Exception {
    mockMvc.perform(
        MockMvcRequestBuilders.post(DISH_ENDPOINT)
          .contentType(MediaType.APPLICATION_JSON)
          .content(objectMapper.writeValueAsString(dishDto)))
      .andExpect(status().isCreated());
  }


public DishDto getMockDish(Long id) throws Exception {
    MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders
        .get(DISH_ENDPOINT + "/{id}", id))
      .andExpect(status().isOk())
      .andReturn();
    String contentAsString = mvcResult.getResponse().getContentAsString();
    return objectMapper.readValue(contentAsString, new TypeReference<>() {
    });
  }

我要完成的工作(我可以在另一个类中自动装配的 bean,例如 DishControllerTest 类):

@AutoConfigureMockMvc
@TestComponent
public class AppMockMcv {
  private static final String DISH_ENDPOINT = "/dishes";
  private static final String BASE_INGREDIENTS_ENDPOINT = "/base-ingredients";

  @Autowired
  private MockMvc mockMvc;
  @Autowired
  private ObjectMapper objectMapper;

  public List<DishDto> getMockDishes() throws Exception {
  ...

我想如何实例化我的测试类:

@SpringBootTest
public class DishControllerTest {

  @Autowired
  private AppMockMcv appMockMcv;

  @Test
  void testGetDishes() throws Exception {
    List<DishDto> dishes = appMockMcv.getMockDishes();
    assertEquals(4, dishes.size());
    assertNotNull(dishes);
    DishAssertions.containsDish(dishes, "Pasta Carbonara");
  }

现在我面临的问题是我不能将@AutoConfigureMockMvc 与@TestComponent 一起使用,在自动装配中找不到bean。我还在 AppMockMcv 类中尝试了@Component、@TestConfiguration、@SpringBootTest 注释。

当前错误,虽然不是很有用:

No qualifying bean of type 'mtv.restaurant.mock.AppMockMcv' available: 
expected at least 1bean which qualifies as autowire candidate. 
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)

我没有找到太多关于如何创建仅用于测试的 bean 以及如何将其与 AutoConfigureMockMvc 结合使用的信息。另外,我试图找到一种方法来扩展 MockMvc 却没有成功。

实现我想要实现的目标的正确方法是什么?

标签: javaspringspring-bootspring-mvcspring-mvc-test

解决方案


我没有找到太多关于如何创建仅用于测试的 bean 以及如何将其与 AutoConfigureMockMvc 结合使用的信息。另外,我试图找到一种方法来扩展 MockMvc 却没有成功。

如果您在 /test/java 下创建 bean,那么它只会在测试中使用(在大多数情况下),即使使用了组件注释。在此处查看信息 - https://docs.spring.io/spring-boot/docs/1.4.3.RELEASE/reference/html/boot-features-testing.html (40.3.2)。

另外,我写了一些代码,例如,它可以工作(因为你没有为 Spring 提供配置,我只使用了@SpringBootApplication):

包源:

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

包 src.test:

@Component
public class CustomMockMVc {
    public MockMvc getMockMvc() {
        return mockMvc;
    }

    private final MockMvc mockMvc;

    public CustomMockMVc(MockMvc mockMvc) {
        this.mockMvc = mockMvc;
    }
}

@SpringBootTest
@AutoConfigureMockMvc
public class TestComponent {
    @Autowired
    private CustomMockMVc customMockMVc;

    @Test
    public void testMockMvc() {
        System.out.println(customMockMVc.getMockMvc());
    }
}

推荐阅读