如何为多个测试 classes 创建一个通用的 MockMvc class?
How to create a general MockMvc class for multiple test classes?
我正在为许多不同的 Spring 控制器编写端到端测试。现在,我正在尝试编写一个通用的 class 用于测试,其中包含 MockMvc 执行方法。我有需要在不同控制器中调用的端点,我不想复制粘贴代码,并且在每个测试中都有一个 MockMvc 和 ObjectMapper class。
几个方法的例子:
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<>() {
});
}
我想要完成的事情(我可以在另一个 class 中自动装配的 bean,DishControllerTest class 中的示例):
@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 {
...
我想如何实例化我的测试classes:
@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 class.
中尝试了 @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 但没有成功。
实现我想要完成的目标的正确方法是什么?
- Spring 启动 2.5.4
呵呵,学了之后Spring Boot基本就忘得差不多了Java...
我想到的解决方案是我在 xControllerTest class 中使用 @Autowire 和 @AutoConfigureMockMvc,并创建一个 AppMockMcv @BeforeAll 测试实例,我在其中传入 MockMvc 和 ObjectMapper。
这样我就可以调用我的请求,并且只有一个 Mvc 执行方法 class。
我会分享我的解决方案,但如果有人分享更好的解决方案,我将不胜感激,因为这不是正确的做法。
AppMockMcv:
public class AppMockMcv {
private static final String DISH_ENDPOINT = "/dishes";
private static final String BASE_INGREDIENTS_ENDPOINT = "/base-ingredients";
private final MockMvc mockMvc;
private final ObjectMapper objectMapper;
public AppMockMcv(MockMvc mockMvc, ObjectMapper objectMapper) {
this.mockMvc = mockMvc;
this.objectMapper = objectMapper;
}
public List<DishDto> getMockDishes() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders
.get(DISH_ENDPOINT)
.queryParam("custom", "false"))
.andExpect(status().isOk())
.andReturn();
String contentAsString = mvcResult.getResponse().getContentAsString();
return objectMapper.readValue(contentAsString, new TypeReference<>() {
});
}
}
DishControllerTest:
@AutoConfigureMockMvc
@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class DishControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
private AppMockMcv appMockMcv;
@BeforeAll
public void setup() {
appMockMcv = new AppMockMcv(mockMvc, objectMapper);
}
@Test
void testGetDishes() throws Exception {
List<DishDto> dishes = appMockMcv.getMockDishes();
assertEquals(4, dishes.size());
assertNotNull(dishes);
DishAssertions.containsDish(dishes, "Pasta Carbonara");
}
}
I did not find much information on how to create a bean for testing
only, also on how to combine it with AutoConfigureMockMvc. Also, I
tried to find a way on how to extend MockMvc without success.
如果你在/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());
}
}
我正在为许多不同的 Spring 控制器编写端到端测试。现在,我正在尝试编写一个通用的 class 用于测试,其中包含 MockMvc 执行方法。我有需要在不同控制器中调用的端点,我不想复制粘贴代码,并且在每个测试中都有一个 MockMvc 和 ObjectMapper class。
几个方法的例子:
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<>() {
});
}
我想要完成的事情(我可以在另一个 class 中自动装配的 bean,DishControllerTest class 中的示例):
@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 {
...
我想如何实例化我的测试classes:
@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 class.
中尝试了 @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 但没有成功。
实现我想要完成的目标的正确方法是什么?
- Spring 启动 2.5.4
呵呵,学了之后Spring Boot基本就忘得差不多了Java...
我想到的解决方案是我在 xControllerTest class 中使用 @Autowire 和 @AutoConfigureMockMvc,并创建一个 AppMockMcv @BeforeAll 测试实例,我在其中传入 MockMvc 和 ObjectMapper。
这样我就可以调用我的请求,并且只有一个 Mvc 执行方法 class。
我会分享我的解决方案,但如果有人分享更好的解决方案,我将不胜感激,因为这不是正确的做法。
AppMockMcv:
public class AppMockMcv {
private static final String DISH_ENDPOINT = "/dishes";
private static final String BASE_INGREDIENTS_ENDPOINT = "/base-ingredients";
private final MockMvc mockMvc;
private final ObjectMapper objectMapper;
public AppMockMcv(MockMvc mockMvc, ObjectMapper objectMapper) {
this.mockMvc = mockMvc;
this.objectMapper = objectMapper;
}
public List<DishDto> getMockDishes() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders
.get(DISH_ENDPOINT)
.queryParam("custom", "false"))
.andExpect(status().isOk())
.andReturn();
String contentAsString = mvcResult.getResponse().getContentAsString();
return objectMapper.readValue(contentAsString, new TypeReference<>() {
});
}
}
DishControllerTest:
@AutoConfigureMockMvc
@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class DishControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
private AppMockMcv appMockMcv;
@BeforeAll
public void setup() {
appMockMcv = new AppMockMcv(mockMvc, objectMapper);
}
@Test
void testGetDishes() throws Exception {
List<DishDto> dishes = appMockMcv.getMockDishes();
assertEquals(4, dishes.size());
assertNotNull(dishes);
DishAssertions.containsDish(dishes, "Pasta Carbonara");
}
}
I did not find much information on how to create a bean for testing only, also on how to combine it with AutoConfigureMockMvc. Also, I tried to find a way on how to extend MockMvc without success.
如果你在/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());
}
}