简体   繁体   English

为什么 Spring 启动 controller 测试返回 404,但在上下文中找到 controller?

[英]Why Spring Boot controller test returning 404, but controller found in context?

I've got a REST controller I'm trying to test, but when attempting to POST to it, I get a 404. The test is JUnit 5 and Spring Boot 2.1.5. I've got a REST controller I'm trying to test, but when attempting to POST to it, I get a 404. The test is JUnit 5 and Spring Boot 2.1.5. If I run the application, I can hit the controller via Postman.如果我运行应用程序,我可以通过 Postman 访问 controller。 I've run it in debug mode and verified that myController is not null and has the mocked services injected into it.我已经在调试模式下运行它并验证myController不是 null 并且已将模拟服务注入其中。 What am I missing here?我在这里想念什么? spring-boot-starter-test is a dependency, and junit4 is an exclusion. spring-boot-starter-test 是一个依赖项,而 junit4 是一个排除项。

@RestController
@Slf4j
@RequestMapping(path = /integrations,
    produces = "application/json")
public class MyController {

    private MyService myService;
    private MyValidationService myValidationService;

    public MyController(MySerivce service, MyValidationService myValidationService) {
        this.myService = service;
        this.myValidationService = myValidationService;
    }

    @PostMapping(path = "/users", produces = "application/json", consumes = 
                                       "application/json")
    public ResponseEntity<User> getUserList(@Valid @RequestBody final RequestPayload 
          requestPayload, @RequestHeader Map<String, String> headers) throws MyException {
        // check the credentials and permission
        Map<String, String> credInfo = myValidationService.validateHeaders(headers);

        // process payload
        return myService.retrieveUsers(requestPayload);


    }
}

Test is as follows:测试如下:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc
class MyControllerTest {

    @MockBean
    private MyService myService;

    @MockBean
    private MyValidationService myValidationService;

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    MyController myController;

    @Test
    public void contextLoads() throws Exception {
        Assert.assertNotNull(myController);
    }

    @Test
    void getUserList() throws Exception {
        List<User> users = returnUserList();
        HttpEntity<RequestPayload> requestHttpEntity = new HttpEntity<>(returnPayload(), null);
        when(myService.retrieveUsers(any(RequestPayload.class))).thenReturn(users);
        mockMvc.perform(post("/integrations/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content(asJsonString(returnPayload()))
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().is2xxSuccessful());

    }
}

The response I get is:我得到的回应是:

MockHttpServletResponse:
           Status = 404
    Error message = null
          Headers = []
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

I appreciate the answers, but I discovered what the problem was - and it was a bonehead one!我很欣赏这些答案,但我发现了问题所在 - 这是一个愚蠢的问题!

It turns out that I included the context path in the mockMvc call when that value is already provided in the application.properties file!事实证明,当application.properties文件中已经提供了该值时,我在 mockMvc 调用中包含了上下文路径! So instead of a URI of /integrations/users , the real URI being used was /integrations/integrations/users , which unsurprisingly does not exist!因此,使用的真正 URI 不是/integrations/users的 URI,而是/integrations/integrations/users ,这并不奇怪!

Thanks to all and sorry for not taking my eyes in my hands and looking more closely.感谢所有人,很抱歉没有把我的眼睛放在我的手中并仔细观察。

You can use a slice test annotation instead.您可以改用切片测试注释。 For testing a controller you can use @WebMvcTest.要测试 controller,您可以使用 @WebMvcTest。

Your setup would look like this:您的设置如下所示:

@SpringBootTest(value = MyController.class)
@ExtendWith(SpringExtension.class)
class MyControllerTest { 

You can still @Autowired the MockMvc.你仍然可以@Autowired MockMvc。 Also there is no need to autowire your controller in the test.此外,无需在测试中自动连接您的 controller。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM