Java 如何在Spring Boot WebMvcTest中设置上下文路径
我试图从我的Spring Boot应用程序测试我的Rest控制器,并希望这些控制器可以在生产中的相同路径下使用 例如,我有以下控制器:Java 如何在Spring Boot WebMvcTest中设置上下文路径,java,spring,rest,spring-mvc,spring-boot,Java,Spring,Rest,Spring Mvc,Spring Boot,我试图从我的Spring Boot应用程序测试我的Rest控制器,并希望这些控制器可以在生产中的相同路径下使用 例如,我有以下控制器: @RestController @交易的 公共类MyController{ 私有最终MyRepository存储库; @自动连线 公共MyController(MyRepository存储库){ this.repository=存储库; } @请求映射(value=“/myentity/{id}”, method=RequestMethod.GET, produ
@RestController
@交易的
公共类MyController{
私有最终MyRepository存储库;
@自动连线
公共MyController(MyRepository存储库){
this.repository=存储库;
}
@请求映射(value=“/myentity/{id}”,
method=RequestMethod.GET,
products=MediaType.APPLICATION\u JSON\u值)
@应答器
公共责任(
@PathVariable(value=“id”)长id{
MyEntity实体=repository.findOne(id);
if(实体==null){
返回新的ResponseEntity(未找到HttpStatus.NOT_);
}
返回新的响应属性(实体,HttpStatus.OK);
}
}
在我的应用程序.yml
中,我已为应用程序配置了上下文路径:
server:
contextPath: /testctx
我对该控制器的测试如下所示:
@RunWith(SpringRunner.class)
@WebMvcTest(controllers=MyController.class,secure=false)
公共类MyControllerTest{
@自动连线
私有MyRepositoryRepositoryMock;
@自动连线
私有MockMvc;
@试验
public void testGet()引发异常{
MyEntity实体=新的MyEntity();
实体。setId(10L);
当(repositoryMock.findOne(10L)),然后返回(实体);
MockHttpServletResponse=this.mvc.perform(
MockMvcRequestBuilders.get(“/testctx/myentity/10”))
.andReturn().getResponse();
assertEquals(response.getStatus(),200);
}
@测试配置
公共静态类TestConfig{
@豆子
MyRepo(){
返回mock(MyRepository.class);
}
}
}
此测试失败,因为呼叫的状态代码为404。如果我调用/myentity/10
,它会工作。不幸的是,rest调用是由CDC测试框架(pact)启动的,因此我无法更改请求的路径(包含上下文路径/testctx
)。那么,有没有一种方法可以告诉spring boot test在测试期间也使用定义的上下文路径启动rest端点?您可以尝试:
@WebMvcTest(controllers = {MyController.class})
@TestPropertySource(locations="classpath:application.properties")
class MyControllerTest {
@Autowired
protected MockMvc mockMvc;
@Value("${server.servlet.context-path}")
private String contextPath;
@BeforeEach
void setUp() {
assertThat(contextPath).isNotBlank();
((MockServletContext) mockMvc.getDispatcherServlet().getServletContext()).setContextPath(contextPath);
}
protected MockHttpServletRequestBuilder createGetRequest(String request) {
return get(contextPath + request).contextPath(contextPath)...
}
它们是相同的,但是您编写的是单元测试,而不是集成测试。您正在单独测试控制器,因此它不会对servlet路径做任何事情。如果你想这样做,你必须让它成为一个合适的集成测试。但是在您的测试中使用
/myentity/10
并让您的其他测试套件调用实际的应用程序有什么不对……我担心在单元测试时没有机会这样做。。。上面的代码只是一个示例。在我的实际测试中,Pact框架钩住并执行请求。在测试中,我没有机会截获来自Pact的调用,以摆脱上下文路径。因为我想要一个快速的单元测试,而不是一个缓慢的集成测试,所以我一直在寻找一种方法来设置上下文路径,甚至是为模拟控制器设置上下文路径。我现在更新了Pact框架,并在发送请求之前删除了上下文路径。