gpt4 book ai didi

java - Spring/Thymeleaf 单元测试 : test does not send value for model correctly

转载 作者:行者123 更新时间:2023-11-30 06:27:42 24 4
gpt4 key购买 nike

我正在为我的代码编写单元测试。现在我想测试放入表单中的值是否正确保存在 Controller 的变量中。依赖于该模型属性是否正确的两个测试都会失败。因为模型存在但保持为空,这一定意味着我以错误的方式发送测试中的值。如何让我的测试包含输入的值以正确测试 post 方法?

测试 testPostValueInModel() 失败并出现断言错误:

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

我必须注意,我对这一切都很陌生,所以如果有人有答案,请提供更多代码示例并解释出了什么问题,以便我可以从错误中学习。谢谢。

这是我的测试类:

@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("chosenTemp"));
} 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("chosenTemp"));
} catch (Exception e) {
e.printStackTrace();
}
}
}

Controller :

@Controller
public class InvoerschermController {

private String chosenTemp = "20";
private static PostgresDatabase database;
private static Connection connection;

// Static initializer for the database
static {
database = new PostgresDatabase();
connection = database.connectToDatabase();
}

@GetMapping("/invoer")
public String invoer(Model model) {
// int newTemp = Integer.parseInt(getChosenTemp());
chosenTemp = database.getTemperature(connection);
model.addAttribute("chosenTemp", getChosenTemp());
return "invoerscherm";
}

@PostMapping("/invoer")
public String addInputTemp(String chosenTemp, Model model) {
setChosenTemp(chosenTemp);
model.addAttribute("chosenTemp", getChosenTemp());

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

return "invoerscherm";
}

public String getChosenTemp() {
return chosenTemp;
}

public void setChosenTemp(String chosenTemp) {
this.chosenTemp = chosenTemp;
}
}

百里叶:

<!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>Temperatuur instellen</h1>
</div>

<form action="#" th:action="@{/invoer}" th:object="${invoerscherm}"
method="post">
<div class="form-group">
<label for="chosenTemp">Gewenste temperatuur:</label> <input
type="text" class="form-control" id="chosenTemp" name="chosenTemp"
autocomplete="off" th:value="${chosenTemp}" />
</div>

<button type="submit" class="btn btn-default" name="submitKnop">Stel
in</button>
</form>
</div>

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

最佳答案

首先你的 Controller 有缺陷。您不应该保留本地状态(尝试想象当 3 个用户同时提交时 chosenTemp 字段会发生什么,因为只有一个 InvoerschermController 实例。

您的方法参数应使用 @RequestParam("chosenTemp") 进行注释,以匹配您发送的表单。您的测试还应该反射(reflect)出您正在发送名为 chosenTemp 的参数这一事实。

首先是你的 Controller

@Controller
public class InvoerschermController {

private static PostgresDatabase database;
private static Connection connection;

// Static initializer for the database
static {
database = new PostgresDatabase();
connection = database.connectToDatabase();
}

@GetMapping("/invoer")
public String invoer(Model model) {
Integer chosenTemp = database.getTemperature(connection);
model.addAttribute("chosenTemp", chosenTemp);
return "invoerscherm";
}

@PostMapping("/invoer")
public String addInputTemp(@RequestParam("chosenTemp") Integer chosenTemp, Model model) {
model.addAttribute("chosenTemp", chosenTemp);
database.setTemperature(connection, chosenTemp);
return "invoerscherm";
}
}

注意类型从StringInteger 的变化 Spring 将为您进行类型转换,并注意添加@RequestParam。现在你的测试也应该反射(reflect)这一点。

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

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

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

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

请注意添加 .param("chosenTemp", "20") 以添加具有该名称的请求参数。

您的 Controller 仍然有缺陷,恕我直言,因为它不应该关心应该全部封装在您的Database类中的Connection。尽管您的测试现在可能有效,但由于使用 Thymeleaf 和表单绑定(bind),您的实际应用程序仍然会失败。表单绑定(bind)期望键 invoerScherm 下的对象可用,并且该对象应具有名为 chosenTemp 的属性。你实际上缺少一个表单对象。那么你的 Controller 实际上应该是什么样子。

首先你需要一个表单对象:

public class InvoerScherm {
private Integer chosenTemp;
public InvoerScherm() {}
public InvoerScherm(Integer temp) { this.chosenTemp=temp;}
// Here be getters/setters
}

然后让您的 Controller 创建并使用它

@Controller
public class InvoerschermController {

private static PostgresDatabase database;
private static Connection connection;

// Static initializer for the database
static {
database = new PostgresDatabase();
connection = database.connectToDatabase();
}

@GetMapping("/invoer")
public String invoer(Model model) {
Integer chosenTemp = database.getTemperature(connection);
InvoerScherm invoerScherm = new InvoerScherm(chosenTemp);
model.addAttribute("invoerScherm", invoerScherm);
return "invoerscherm";
}

@PostMapping("/invoer")
public String addInputTemp(@ModelAttribute InvoerScherm invoerScherm, Model model) {
database.setTemperature(connection, invoerScherm.getChosenTemp());
return "invoerscherm";
}
}

当然,现在你的测试会再次失败,但我把这个任务留给你了。

关于java - Spring/Thymeleaf 单元测试 : test does not send value for model correctly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46787344/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com