没有与MockMvc的请求映射

huangapple go评论91阅读模式
英文:

No mapping for request with mockmvc

问题

目前我遇到了一个问题,当我使用以下的控制器/测试配置时,我会得到一个"请求的映射错误"的错误信息。

控制器:

@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
public class AdtechController {

    private final AdtechService adtechService;

    @PostMapping(value = "/subscriber/session")
    public ResponseEntity<ResponseDto> submitSession(@RequestBody RequestDto requestDto) {
        log.trace("execute submitSession with {}", requestDto);
        ResponseDto response = adtechService.submitSession(requestDto);
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

    @ExceptionHandler(AdtechServiceException.class)
    public ResponseEntity<AdtechErrorResponse> handleAdtechServiceException(AdtechServiceException e) {
        return new ResponseEntity<>(new AdtechErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
    }

}

测试:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@SpringJUnitConfig({AdtechTestConfig.class})
public class AdtechControllerTest {

    private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testSubmitSession() throws Exception {
        RequestDto requestDto = new RequestDto ();
        requestDto.setKyivstarId("1123134");
        requestDto.setMsisdn("123476345242");
        requestDto.setPartnerId("112432523");
        requestDto.setPartnerName("125798756");
        String request = OBJECT_MAPPER.writeValueAsString(requestDto);
        System.out.println("REQUEST: " + request);
        String response = OBJECT_MAPPER.writeValueAsString(new ResponseDto("123"));
        System.out.println("RESPONSE: " + response);
        mockMvc.perform(post("/subscriber/session")
                .content(MediaType.APPLICATION_JSON_VALUE)
                .content(request))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().string(containsString(response)));

    }

}

配置:

@Configuration
public class AdtechTestConfig {

    @Bean
    public AdtechService adtechTestService() {
        return requestDto -> new AdtechResponseDto("123");
    }

}

在测试执行后,我得到了"没有映射为POST /subscriber/session"的错误信息。

我遇到困难的原因是我的其他模块的代码使用相同的配置工作正常。有人能指出我漏掉了什么吗?谢谢!

(Note: This translation does not include the code portion.)

英文:

Currently struggling with problem when I get 'mapping error for request' with following controller/test configuration.
Controller:

@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
public class AdtechController {

private final AdtechService adtechService;

@PostMapping(value = &quot;/subscriber/session&quot;)
public ResponseEntity&lt;ResponseDto&gt; submitSession(@RequestBody RequestDto requestDto) {
    log.trace(&quot;execute submitSession with {}&quot;, requestDto);
    ResponseDtoresponse = adtechService.submitSession(requestDto);
    return new ResponseEntity&lt;&gt;(response, HttpStatus.OK);
}

@ExceptionHandler(AdtechServiceException.class)
public ResponseEntity&lt;AdtechErrorResponse&gt; handleAdtechServiceException(AdtechServiceException e) {
    return new ResponseEntity&lt;&gt;(new AdtechErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}

}

Test:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@SpringJUnitConfig({AdtechTestConfig.class})
public class AdtechControllerTest {

private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();

@Autowired
private MockMvc mockMvc;

@Test
public void testSubmitSession() throws Exception {
    RequestDto requestDto = new RequestDto ();
    requestDto.setKyivstarId(&quot;1123134&quot;);
    requestDto.setMsisdn(&quot;123476345242&quot;);
    requestDto.setPartnerId(&quot;112432523&quot;);
    requestDto.setPartnerName(&quot;125798756&quot;);
    String request = OBJECT_MAPPER.writeValueAsString(requestDto);
    System.out.println(&quot;REQUEST: &quot; + request);
    String response = OBJECT_MAPPER.writeValueAsString(new ResponseDto(&quot;123&quot;));
    System.out.println(&quot;RESPONSE: &quot; + response);
    mockMvc.perform(post(&quot;/subscriber/session&quot;)
            .content(MediaType.APPLICATION_JSON_VALUE)
            .content(request))
            .andDo(print())
            .andExpect(status().isOk())
            .andExpect(content().string(containsString(response)));

}

}

Configuration:

@Configuration
public class AdtechTestConfig {

@Bean
public AdtechService adtechTestService() {
    return requestDto -&gt; new AdtechResponseDto(&quot;123&quot;);
}

}

After test execution I get No mapping for POST /subscriber/session

The reason for the struggle is that my code from other modules with the same configuration works fine. Can somebody point out what am I missing ? Thanks in advance!

答案1

得分: 3

显然,你正在加载一个配置类来模拟Bean,这会干扰Spring Boot的其他部分,可能会导致你的应用程序部分加载。我怀疑只有模拟的服务是可用的。

而不是使用测试配置,使用 @MockBean 来创建一个服务的模拟并在其上注册行为。

@SpringBootTest
@AutoConfigureMockMvc
public class AdtechControllerTest {

  private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();

  @Autowired
  private MockMvc mockMvc;
  @MockBean
  private AdtechService mockService;

  @BeforeEach
  public void setUp() {
    when(mockService.yourMethod(any()).thenReturn(new AdtechResponseDto("123")); 
  }


  @Test
  public void testSubmitSession() throws Exception {
    // 你的原始测试方法
  }
}

如果你只想测试控制器,你也可以考虑使用 @WebMvcTest 而不是 @SpringBootTest

@WebMvcTest(AdTechController.class)
public class AdtechControllerTest {

  private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();

  @Autowired
  private MockMvc mockMvc;
  @MockBean
  private AdtechService mockService;

  @BeforeEach
  public void setUp() {
    when(mockService.yourMethod(any()).thenReturn(new AdtechResponseDto("123")); 
  }


  @Test
  public void testSubmitSession() throws Exception {
    // 你的原始测试方法
  }
}

这将加载上下文的精简版本(仅包含Web部分),运行速度更快。

英文:

Apparently you are loading a configuration class to mock beans, this interferes with the other parts of Spring Boot and probably leads to partially loading your application. I suspect only the mocked service is available.

Instead of the test configuration use @MockBean to create a mock for the service and register behaviour on it.

@SpringBootTest
@AutoConfigureMockMvc
public class AdtechControllerTest {

  private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();

  @Autowired
  private MockMvc mockMvc;
  @MockBean
  private AdtechService mockService;

  @BeforeEach
  public void setUp() {
    when(mockService.yourMethod(any()).thenReturn(new AdtechResponseDto(&quot;123&quot;)); 
  }


  @Test
  public void testSubmitSession() throws Exception {
    // Your original test method
  }
}

If the only thing you want to test is your controller you might also want to consider using @WebMvcTest instead of @SpringBootTest.

@WebMvcTest(AdTechController.class)
public class AdtechControllerTest {

  private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();

  @Autowired
  private MockMvc mockMvc;
  @MockBean
  private AdtechService mockService;

  @BeforeEach
  public void setUp() {
    when(mockService.yourMethod(any()).thenReturn(new AdtechResponseDto(&quot;123&quot;)); 
  }


  @Test
  public void testSubmitSession() throws Exception {
    // Your original test method
  }
}

This will load a scaled-down version of the context (only the web parts) and will be quicker to run.

答案2

得分: 1

尝试这个:

@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
public class AdtechController {

    private AdtechService adtechService;

    public AdtechController(AdtechService adtechService) {
        this.adtechService = adtechService;
    }

    @PostMapping(value = "/subscriber/session")
    public ResponseEntity<ResponseDto> submitSession(@RequestBody RequestDto requestDto) {
        log.trace("execute submitSession with {}", requestDto);
        ResponseDto response = adtechService.submitSession(requestDto);
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

    @ExceptionHandler(AdtechServiceException.class)
    public ResponseEntity<AdtechErrorResponse> handleAdtechServiceException(AdtechServiceException e) {
        return new ResponseEntity<>(new AdtechErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
    }

}

测试部分:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@SpringJUnitConfig({AdtechTestConfig.class})
public class AdtechControllerTest {

    private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();

    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private AdtechService adtechService;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        this.mvc = MockMvcBuilders.standaloneSetup(new AdtechController(adtechService)).build();
    }

    @Test
    public void testSubmitSession() throws Exception {
        RequestDto requestDto = new RequestDto();
        requestDto.setKyivstarId("1123134");
        requestDto.setMsisdn("123476345242");
        requestDto.setPartnerId("112432523");
        requestDto.setPartnerName("125798756");
        String request = OBJECT_MAPPER.writeValueAsString(requestDto);
        System.out.println("REQUEST: " + request);
        String response = OBJECT_MAPPER.writeValueAsString(new ResponseDto("123"));
        System.out.println("RESPONSE: " + response);
        mockMvc.perform(post("/subscriber/session")
                .content(MediaType.APPLICATION_JSON_VALUE)
                .content(request))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().string(containsString(response)));
    }

}
英文:

try this:

@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
public class AdtechController {
private AdtechService adtechService;
public AdtechController (AdtechService adtechService) {
this.adtechService= adtechService;
}
@PostMapping(value = &quot;/subscriber/session&quot;)
public ResponseEntity&lt;ResponseDto&gt; submitSession(@RequestBody RequestDto requestDto) {
log.trace(&quot;execute submitSession with {}&quot;, requestDto);
ResponseDtoresponse = adtechService.submitSession(requestDto);
return new ResponseEntity&lt;&gt;(response, HttpStatus.OK);
}
@ExceptionHandler(AdtechServiceException.class)
public ResponseEntity&lt;AdtechErrorResponse&gt; handleAdtechServiceException(AdtechServiceException e) {
return new ResponseEntity&lt;&gt;(new AdtechErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

Test:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@SpringJUnitConfig({AdtechTestConfig.class})
public class AdtechControllerTest {
private static final ObjectMapper OBJECT_MAPPER = JsonUtil.getJackson();
@Autowired
private MockMvc mockMvc;
@Autowired
private AdtechService adtechService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
this.mvc = MockMvcBuilders.standaloneSetup(new AdtechController(adtechService)).build();
}
@Test
public void testSubmitSession() throws Exception {
RequestDto requestDto = new RequestDto ();
requestDto.setKyivstarId(&quot;1123134&quot;);
requestDto.setMsisdn(&quot;123476345242&quot;);
requestDto.setPartnerId(&quot;112432523&quot;);
requestDto.setPartnerName(&quot;125798756&quot;);
String request = OBJECT_MAPPER.writeValueAsString(requestDto);
System.out.println(&quot;REQUEST: &quot; + request);
String response = OBJECT_MAPPER.writeValueAsString(new ResponseDto(&quot;123&quot;));
System.out.println(&quot;RESPONSE: &quot; + response);
mockMvc.perform(post(&quot;/subscriber/session&quot;)
.content(MediaType.APPLICATION_JSON_VALUE)
.content(request))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString(response)));
}
}

答案3

得分: 1

AdtechTestConfig.class 是否将 "/ad-tech" 路径段引入到您的测试请求中?如果是的话,这就是为什么您的测试尝试使用路径 "/ad-tech/subscriber/session" 而不是 "/subscriber/session" 的原因。

如果这实际上是正确的 URI,那么您可以像下面这样为控制器添加 @RequestMapping,或者只添加到 post 方法本身:

@Slf4j
@Validated
@RestController
@RequestMapping("/ad-tech")
@RequiredArgsConstructor
public class AdtechController {

private final AdtechService adtechService;

@PostMapping(value = "/subscriber/session")
public ResponseEntity<ResponseDto> submitSession(@RequestBody RequestDto requestDto) {
...
英文:

Is the AdtechTestConfig.class introducing the /ad-tech path segment in to your test request? If so, this is why your test is trying the path /ad-tech/subscriber/session instead of /subscriber/session.

If this is actually the correct uri, then you may add @RequestMapping to the controller like below or just to the post method itself

@Slf4j
@Validated
@RestController
@RequestMapping(&quot;/ad-tech&quot;)
@RequiredArgsConstructor
public class AdtechController {
private final AdtechService adtechService;
@PostMapping(value = &quot;/subscriber/session&quot;)
public ResponseEntity&lt;ResponseDto&gt; submitSession(@RequestBody RequestDto requestDto) {
...

huangapple
  • 本文由 发表于 2020年8月5日 00:26:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/63251150.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定