Spring Boot / Thymeleaf单元测试:模型属性不存在

时间:2017-10-09 10:40:54

标签: java spring unit-testing spring-boot thymeleaf

我创建了一个视图,其中用户可以输入inputTemp的值,输入保存在Controller的属性中。

查看:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:include="fragments/template :: head"></head>
<head>
  <title>Smart CV</title>
</head>
<body>

<nav th:replace="fragments/template :: header"></nav>

<div class="container">
  <div class="hero-unit">
    <h1>Invoerscherm</h1>
  </div>
</div>

<form action="#" th:action="@{/invoer}" th:object="${invoerscherm}" method="post">
  <td><input type="text" id="inputTemp" name="inputTemp" th:value="${inputTemp}"/></td>
  <td><input name="submitKnop" type="submit" value="Input Temp"/></td>
</form>

<nav th:replace="fragments/template :: footer"></nav>
</body>
</html>

控制器:

@Controller
public class InvoerschermController {

    private String inputTemp = "20";

    @GetMapping("/invoer")
    public String invoer(Model model) {
        model.addAttribute("inputTemp", getInputTemp());
        System.out.println("1: " + model.toString());
        return "invoerscherm";
    }

    @PostMapping("/invoer")
    public String addInputTemp(String inputTemp, Model model) {
        setInputTemp(inputTemp);
        model.addAttribute("inputTemp", getInputTemp());
        System.out.println("2: " + model.toString());

        try {
            int newTemp = Integer.parseInt(getInputTemp());
            PostgresDatabase database = new PostgresDatabase();
            Connection connection = database.connectToDatabase();
            database.setTemperature(connection, newTemp);
        } catch (NumberFormatException nfe) {
            System.err.println("Invalid number: " + nfe.getMessage());
        }

        return "invoerscherm";
    }

    public String getInputTemp() {
        return inputTemp;
    }

    public void setInputTemp(String inputTemp) {
        this.inputTemp = inputTemp;
    }
}

现在,我想写一个UnitTest来检查inputTemp是否正确保存。这些是我的单元测试:

@RunWith(SpringRunner.class)
@WebMvcTest(InvoerschermController.class)
@AutoConfigureMockMvc
public class InvoerschermTest {
    @Autowired
    private MockMvc mockMvc;    

    @Test
    public void testCorrectModel() {
        try {
            this.mockMvc.perform(get("/invoer", "20")).andExpect(status().isOk())
                    .andExpect(model().attributeExists("inputTemp"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testPost() {
        try {
            this.mockMvc.perform(post("/invoer", "20")).andExpect(status().isOk())
                    .andExpect(view().name("invoerscherm"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testPostValueInModel() {
        try {
            this.mockMvc.perform(post("/invoer", "20")).andExpect(status().isOk())
                    .andExpect(model().attributeExists("inputTemp"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

现在我的两个测试失败了(testCorrectModel()和testPostValueInModel()),两者都有以下消息:

java.lang.AssertionError: Model attribute 'inputTemp' does not exist

据我所知,这个属性确实存在,所以某个地方我做错了什么,而我却不知道自己哪里出错了。 编辑:似乎我没有正确地将变量发送到addInputTemp方法。我该怎么做?

1 个答案:

答案 0 :(得分:2)

在函数testCorrectModel,testPostValueInModel中 model属性的值为null,因为在第一种情况下inputTemp的私有字段值为null,在第二种情况下,String inputTemp参数为null。

因此,在这些测试功能中,您实际上正在进行此调用

model.addAttribute("inputTemp", null);

地图的大小为1,因为您在地图中添加了一个属性,但是model()。attributeExists会失败,因为此属性的值为null。

这是spring framework

中attributeExists的内部实现
public ResultMatcher attributeExists(final String... names) {
        return new ResultMatcher() {
            public void match(MvcResult result) throws Exception {
                ModelAndView mav = getModelAndView(result);
                for (String name : names) {
                    assertTrue("Model attribute '" + name + "' does not exist", mav.getModel().get(name) != null);
                }
            }
        };
    }

因此,正确设置inputTemp的值。 例如,对于@RequestMapping(“/ invoer”),如何设置inputTemp的值?在一个不同的功能?也许,你应该把它作为路径变量传递吗?