Spring MockMVC 和 WebMvcTest 未返回预期结果的问题

Issue with Spring MockMVC and WebMvcTest not returning expected results

提问人:Tomás Iglesias 提问时间:11/10/2023 更新时间:11/10/2023 访问量:19

问:

我目前正在开发一个Spring Boot应用程序,在为我的控制器编写测试时遇到了一个问题。我有一个名为 TableController 的控制器类,我正在尝试使用 Spring 的 MockMvc 测试该方法。但是,我没有得到预期的结果,我不确定出了什么问题。getById

这是我的设置:

@WebMvcTest(TableController.class)
@WithMockUser
public class TableControllerTests {

    @Autowired
    private MockMvc mockMvc;
    @MockBean
    private TableService tableService;
    private String rootUri;

    @BeforeEach
    public void setUp(){
        this.rootUri = "/tables";
    }

在我的测试方法中:

@Test
    public void getTableById() throws Exception {
        // Arrange
        Integer id = 1;
        Table table = new Table(id);
        String tableUri = rootUri + "/" + id;    // /tables/1
        when(this.tableService.getById(id)).thenReturn(table);

        // Act
        RequestBuilder request = MockMvcRequestBuilders.get(tableUri, id)
                .accept(MediaType.APPLICATION_JSON);

        // Assert
        this.mockMvc.perform(request)
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON))
                .andExpect(jsonPath("$.id", is(id)));
    }

这是我的控制器:

@RestController
@RequestMapping("/tables")
public class TableController {
    @Autowired
    TableService tableService;

    @GetMapping("/{id}")
    public ResponseEntity<Table> getById(@PathVariable Integer id){
        Table table = this.tableService.getById(id);

        if (table != null) {
            return ResponseEntity.ok(table); // 200 OK
        } else {
            return ResponseEntity.notFound().build(); // 404 Not Found
        }
    }

问题是我收到 404 错误而不是预期结果。似乎 TableController 没有返回我在 TableService 中嘲笑的内容。我不确定配置中是否缺少某些内容,或者我的测试设置是否存在问题。

关于可能导致此问题的原因以及如何解决该问题的任何指导将不胜感激。谢谢!

java spring-boot spring-mvc 测试

评论

0赞 M. Deinum 11/10/2023
MockMvcRequestBuilders.get(tableUri, id)将导致一个没有任何映射形式的 URL。要么使用模式,要么省略 in te 方法。/tables/1/1idget

答:

0赞 M. Deinum 11/10/2023 #1

问题出在您的测试设置上。 将导致没有映射的 URL。若要解决此问题,请使用 URL 模式作为属性,或者从调用中省略参数。MockMvcRequestBuilders.get(tableUri, id)/tables/1/1/tables/{id}tableUriidget

String tableUri = rootUri + "/{id}";
RequestBuilder request = MockMvcRequestBuilders.get(tableUri, id)
                .accept(MediaType.APPLICATION_JSON);

RequestBuilder request = MockMvcRequestBuilders.get(tableUri)
                .accept(MediaType.APPLICATION_JSON);

两者都应该有效。

评论

0赞 Tomás Iglesias 11/19/2023
谢谢!有了这个并向我的实体类添加一个 getter,问题就解决了!