如何在Spring Boot WebMvcTest中设置上下文路径

时间:2016-09-13 11:45:27

标签: java spring rest spring-mvc spring-boot

我正在尝试从我的Spring Boot应用程序测试我的Rest控制器,并希望控制器在生产中的路径下可用。

例如,我有以下控制器:

@RestController
@Transactional
public class MyController {

    private final MyRepository repository;

    @Autowired
    public MyController(MyRepository repository) {
        this.repository = repository;
    }

    @RequestMapping(value = "/myentity/{id}",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResponseEntity<Resource<MyEntity>> getMyEntity(
            @PathVariable(value = "id") Long id) {
        MyEntity entity = repository.findOne(id);

        if (entity == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        return new ResponseEntity<>(entity, HttpStatus.OK);
    }
}

在我的application.yml中,我已为应用程序配置了上下文路径:

server:
  contextPath: /testctx

我对此控制器的测试如下:

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = MyController.class, secure=false)
public class MyControllerTest {

    @Autowired
    private MyRepository repositoryMock;

    @Autowired
    private MockMvc mvc;

    @Test
    public void testGet() throws Exception {
        MyEntity entity = new MyEntity();
        entity.setId(10L);
        when(repositoryMock.findOne(10L)).thenReturn(entity);

        MockHttpServletResponse response = this.mvc.perform(
            MockMvcRequestBuilders.get("/testctx/myentity/10"))
            .andReturn().getResponse();
        assertEquals(response.getStatus(), 200);
    }

    @TestConfiguration
    public static class TestConfig {
        @Bean
        MyRepository mockRepo() {
            return mock(MyRepository.class);
        }
    }
}

此测试失败,因为呼叫的状态代码为404。如果我拨打/myentity/10它就可以了。不幸的是,其余的调用是由CDC-Test-Framework(pact)发起的,因此我无法更改请求的路径(包含上下文路径/testctx)。那么有没有办法告诉spring boot test在测试过程中使用定义的上下文路径启动其余端点?

1 个答案:

答案 0 :(得分:0)

你可以试试:

@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)...
    }