【问题标题】:Spring MVC test post method with controller redirect带有控制器重定向的 Spring MVC 测试发布方法
【发布时间】:2017-08-23 14:27:14
【问题描述】:

我有一个测试:

@Test
public void shouldAddCompany() throws Exception {
    mockMvc.perform(post("/companies")
            .param("name", "companyName"))
            .andExpect(model().attribute("company",
                    hasProperty("name", is("companyName"))));

}

我的控制器方法看起来像这样:

@PostMapping("/companies")
public String displayCompaniesPost(@ModelAttribute Company company) {
    companyService.save(company);
    return "redirect:/companies";
}

如何在测试中查看公司属性?由于重定向和状态 302 存在问题。

 java.lang.AssertionError: Model attribute 'company'
 Expected: hasProperty("name", is "companyName")
 but: was null

我认为这是因为控制器将因为重定向而使用 GET 方法。当我删除此重定向时,一切正常,但我不想删除该重定向。

编辑(获取映射):

@GetMapping({"/", "/companies"})
public String displayCompanies(Model model) {
    model.addAttribute("company", new Company());
    List<Company> companies = companyService.findAll();
    model.addAttribute("companies", companies);
    return "companies";
}

我认为问题是因为在getMapping中添加了同名的属性,但是当我删除它时,它仍然不起作用。

【问题讨论】:

  • 你能告诉我们你要重定向的路径的控制器方法是什么样的吗(@GetMapping("/companies"))?
  • @Ben 好的,我已经编辑了第一篇文章。我认为问题是因为在getMapping中添加了同名的属性,但是当我删除它时,它仍然不起作用。 :(
  • 您的测试期望 Companies 属性的名称为 "companyName",但在 GET 中您要添加一个新的 Company,我认为它没有名称。您的测试可能应该寻找companies,因为这是您要重定向到的控制器方法返回的属性。

标签: spring spring-mvc testing spring-boot mocking


【解决方案1】:

您需要修改您的方法。如果您 POST 到控制器方法,并且它返回一个重定向,您将无法访问该控制器设置的任何模型信息,它只会向客户端返回一个带有 Location Header 的 HTTP 302,告诉它要转到的新 url (在这种情况下GET /companies)。如果这是一个严格的单元测试,那就是您可以测试此方法的范围。

我会考虑将其视为集成测试,并将您的测试更改为具有两个单独的步骤:

  1. POST /companies 并验证响应是预期的重定向
  2. GET /companies 并验证返回的公司列表是否包含您在步骤 1 中发布的新公司

【讨论】:

  • 好的,但是当我发布 /companies 时,它会在我的数据库中创建新公司。我应该为测试创建一个新的数据库还是什么?
  • 是的,这就是我的建议,如果您想获得不通过其接口公开的方法的效果,您将需要使用数据存储进行测试。这是内存数据库的一个很好的用法,比如 h2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-01
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多