【问题标题】:Spring JUnit Expected Status 200 but was 404Spring JUnit 预期状态为 200,但为 404
【发布时间】:2022-01-17 03:20:46
【问题描述】:

我正在使用 JUnit 来测试应用程序的路由。问题是我正在向路由发出 PUT 请求,我认为它应该返回状态 200,但实际上它返回 404。我已经尝试过传递一个字符串并将 PathVariable 更改为字符串,使用 Long.parseLong( ) 但我仍然得到错误。我想知道为什么它返回 404 以及我做错了什么,当我的数据库中存在 ID 为 1 的 Persona 和 ID 为 1 的 Grupo 时。顺便说一句,我正在使用 JHipster 并且我正在 PersonaResourceIT 中进行这些测试已经定义了。非常感谢,代码如下:

角色资源:

@PutMapping("/personas/{id}/grupo/{idGrupo}")
public ResponseEntity<Void> vincularGrupo(@PathVariable Long id, @PathVariable Long idGrupo) {
    log.debug("REST request to vincularGrupo : {}", id);
    Optional<Persona> persona = personaRepository.findById(id);
    if (persona.isPresent()) {
        Persona persona2 = persona.get();
        Optional<Grupo> grupo = grupoRepository.findById(idGrupo);
        if (grupo.isPresent()) {
            Grupo grupo2 = grupo.get();
            persona2.setGrupo(grupo2);
            personaRepository.save(persona2);
            return ResponseEntity.ok().build();
        } else {
            return ResponseEntity.notFound().build();
        }
    } else {
        return ResponseEntity.notFound().build();
    }
}

PersonaResourceIT:

    @Test
    @Transactional
    void asociarPersonaGrupoSuccess() throws Exception {
        // Long id = (long) 1;
        // Long idGrupo = (long) 1;
        String id = "1";
        String idGrupo = "1";
        this.restPersonaMockMvc.perform(put("/api/personas/{id}/grupo/{idGrupo}", id, idGrupo))
                                .andExpect(status().isOk())
                                .andReturn();
    }

我也尝试过使用 Long id = 1L 但它不起作用。我不断收到 404 状态。

【问题讨论】:

  • 首先您必须确定数据库中缺少哪个实体,在调试器下应该很容易。然后,您应该查看创建这些实体的方式和时间,是在测试执行之前,在同一事务中,使用 liquibase 吗?
  • 是的,它正在使用 Liquibase。问题是,在我的 application.yml 中,我没有表明我想使用 csv 文件进行集成测试,正如我向 geco17 指出的那样。非常感谢盖尔。每次我从 JHipster 那里学到新东西。

标签: java spring testing junit jhipster


【解决方案1】:

我建议通过一些重构来修改您的代码。

将大部分方法移动到这样的服务中

public int findAndSave(long id, long idGrupo) {
    Optional<Persona> persona = personaRepository.findById(id);
    if (!persona.isPresent()) {
        return 1;
    }
    Optional<Grupo> grupo = grupoRepository.findById(idGrupo);
    if (!grupo.isPresent()) {
        return 2;
    }
    Persona persona2 = persona.get();
    Grupo grupo2 = grupo.get();
    persona2.setGrupo(grupo2);
    personaRepository.save(persona2);
    return 0;
}

那么调用者有

@PutMapping("/personas/{id}/grupo/{idGrupo}")
public ResponseEntity<Void> vincularGrupo(@PathVariable Long id, @PathVariable Long idGrupo) {
    log.debug("REST request to vincularGrupo : {}", id);
    int result = vincularService.findAndSave(id, idGrupo);
    if (result == 0) {
        return ResponseEntity.ok().build();
    }
    // handle 1, 2 or other error codes however you need to
    return ResponseEntity.notFound().build();
}

并且测试被简化:您可以为vincularService 注入一个模拟并测试您是否到达了端点(即它没有给您一个未找到,因为 url 错误),您可以测试vincularService 内部的逻辑独立于它的调用方式(休息或其他方式)。

【讨论】:

  • 非常感谢geco17。我刚刚创建了服务,但仍然得到 404。是因为我必须将其作为字符串而不是 Long 1L 传递吗?然而,这对我来说似乎很奇怪,因为其他端点与 Long 一起工作得很好。有问题的是这一个和另外两个。在我的数据库中存在这些 id,所以我不明白为什么它返回 404。而且路线指定正确,这很奇怪。此外,当我使用 Postman 对其进行测试时,它工作正常。
  • 我不确定,那可能与junit测试有关吗? url 在那里定义为/api/personas/{id}/grupo/{idGrupo},但它在控制器中定义,没有/api 前缀
  • 诺诺。只有在我的 PersonaResource 中我有以下注释:@RequestMapping("/api") public class PersonaResource { 问题是当使用 JHipster 时,我必须在 application.yml 中指出我想使用 csv 数据伪造器才能在集成测试中使用。像这样:liquibase: contexts: prod, faker
猜你喜欢
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-15
相关资源
最近更新 更多