英文:
AssertionError when testing LocalDate with MockMvc and JUnit 5
问题
我正在尝试在Spring Boot 2.3项目中使用JUnit 5与Hibernate 5.4和MockMvc。
这是我的employee实体类的成员字段示例:
import java.time.LocalDate;
...(其余的导入)
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long employeeId;
@Column(nullable = false, updatable = true)
private String firstName;
@Column(nullable = true, updatable = true)
private String lastName;
@Column(nullable = false, updatable = true)
private String email;
@Column(nullable = false, updatable = true)
private LocalDate birthDate;
}
我试图使用JUnit 5、Mockito和MockMvc来测试birthDate字段,测试用例如下:
@Test
public void testFindEmployeeById() throws Exception {
Employee mockedEmployee = makeEmployee(9L, "Mock First", "Mock Last", "mock@email.com",
LocalDate.of(1996, 9, 8), 9L, "Mock Project", "Mock Department");
Mockito.when(employeeRepositoryMock.findById(mockedEmployee.getEmployeeId()))
.thenReturn(Optional.of(mockedEmployee));
mockMvc.perform(MockMvcRequestBuilders.get("/v1/employees/id/9").accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcRestDocumentation.document("employeeById",
Preprocessors.preprocessRequest(Preprocessors.prettyPrint()),
PayloadDocumentation.responseFields(
PayloadDocumentation.fieldWithPath("employeeId").description("Employee ID"),
PayloadDocumentation.fieldWithPath("firstName").description("First Name"),
PayloadDocumentation.fieldWithPath("lastName").description("Last Name"),
PayloadDocumentation.fieldWithPath("email").description("Email Address"),
PayloadDocumentation.fieldWithPath("birthDate").description("Date of Birth"),
PayloadDocumentation.fieldWithPath("project.projectId").description("Project ID"),
PayloadDocumentation.fieldWithPath("project.name").description("Project name"),
PayloadDocumentation.fieldWithPath("project.department.departmentId")
.description("Department ID"),
PayloadDocumentation.fieldWithPath("project.department.name")
.description("Department Name"))))
.andDo(print()).andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.employeeId").value(mockedEmployee.getEmployeeId()))
.andExpect(MockMvcResultMatchers.jsonPath("$.firstName").value(mockedEmployee.getFirstName()))
.andExpect(MockMvcResultMatchers.jsonPath("$.lastName").value(mockedEmployee.getLastName()))
.andExpect(MockMvcResultMatchers.jsonPath("$.email").value(mockedEmployee.getEmail()))
.andExpect(MockMvcResultMatchers.jsonPath("$.birthDate").value(mockedEmployee.getBirthDate()))
.andExpect(MockMvcResultMatchers.jsonPath("$.project.projectId")
.value(mockedEmployee.getProject().getProjectId()))
.andExpect(
MockMvcResultMatchers.jsonPath("$.project.name").value(mockedEmployee.getProject().getName()))
.andExpect(MockMvcResultMatchers.jsonPath("$.project.department.departmentId")
.value(mockedEmployee.getProject().getDepartment().getDepartmentId()))
.andExpect(MockMvcResultMatchers.jsonPath("$.project.department.name")
.value(mockedEmployee.getProject().getDepartment().getName()));
}
在运行测试用例时,我收到了一个AssertionError:
java.lang.AssertionError: JSON path "$.birthDate" expected:<1996-09-08> but was:<1996-09-08>
如您所见,两个字符串表示都相同。但是JUnit 5引发了错误。
那么,正确的比较LocalDate的方式是什么呢?
类似的问题可以在这里找到:https://stackoverflow.com/questions/61184154/comparing-localdate-using-hamcrest-in-junit-test-case
和这里:https://stackoverflow.com/questions/45592405/junit-assertionerror-when-testing-simpledateformat
提前谢谢。 ![]()
英文:
I am trying to use JUnit 5 with Hibernate 5.4 and MockMvc in a Spring Boot 2.3 project.
This is how the members of my employee entity class looks like:
import java.time.LocalDate;
... (Rest of the imports)
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long employeeId;
@Column(nullable = false, updatable = true)
private String firstName;
@Column(nullable = true, updatable = true)
private String lastName;
@Column(nullable = false, updatable = true)
private String email;
@Column(nullable = false, updatable = true)
private LocalDate birthDate;
I am trying to test the LocalDate field birthDate with Mockito and MockMvc using JUnit 5. This is how the test case for that looks like:
@Test
public void testFindEmployeeById() throws Exception {
Employee mockedEmployee = makeEmployee(9L, "Mock First", "Mock Last", "mock@email.com",
LocalDate.of(1996, 9, 8), 9L, "Mock Project", "Mock Department");
Mockito.when(employeeRepositoryMock.findById(mockedEmployee.getEmployeeId()))
.thenReturn(Optional.of(mockedEmployee));
mockMvc.perform(MockMvcRequestBuilders.get("/v1/employees/id/9").accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcRestDocumentation.document("employeeById",
Preprocessors.preprocessRequest(Preprocessors.prettyPrint()),
PayloadDocumentation.responseFields(
PayloadDocumentation.fieldWithPath("employeeId").description("Employee ID"),
PayloadDocumentation.fieldWithPath("firstName").description("First Name"),
PayloadDocumentation.fieldWithPath("lastName").description("Last Name"),
PayloadDocumentation.fieldWithPath("email").description("Email Address"),
PayloadDocumentation.fieldWithPath("birthDate").description("Date of Birth"),
PayloadDocumentation.fieldWithPath("project.projectId").description("Project ID"),
PayloadDocumentation.fieldWithPath("project.name").description("Project name"),
PayloadDocumentation.fieldWithPath("project.department.departmentId")
.description("Department ID"),
PayloadDocumentation.fieldWithPath("project.department.name")
.description("Department Name"))))
.andDo(print()).andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.employeeId").value(mockedEmployee.getEmployeeId()))
.andExpect(MockMvcResultMatchers.jsonPath("$.firstName").value(mockedEmployee.getFirstName()))
.andExpect(MockMvcResultMatchers.jsonPath("$.lastName").value(mockedEmployee.getLastName()))
.andExpect(MockMvcResultMatchers.jsonPath("$.email").value(mockedEmployee.getEmail()))
.andExpect(MockMvcResultMatchers.jsonPath("$.birthDate").value(mockedEmployee.getBirthDate()))
.andExpect(MockMvcResultMatchers.jsonPath("$.project.projectId")
.value(mockedEmployee.getProject().getProjectId()))
.andExpect(
MockMvcResultMatchers.jsonPath("$.project.name").value(mockedEmployee.getProject().getName()))
.andExpect(MockMvcResultMatchers.jsonPath("$.project.department.departmentId")
.value(mockedEmployee.getProject().getDepartment().getDepartmentId()))
.andExpect(MockMvcResultMatchers.jsonPath("$.project.department.name")
.value(mockedEmployee.getProject().getDepartment().getName()));
}
Upon running the test case, I get an AssertionError:
java.lang.AssertionError: JSON path "$.birthDate" expected:<1996-09-08> but was:<1996-09-08>
As you can tell, both the string representations are the same. Yet JUnit 5 throws the error.
So, what is the right way to go about comparing LocalDate with JUnit 5?
A similar question can be found here: https://stackoverflow.com/questions/61184154/comparing-localdate-using-hamcrest-in-junit-test-case
and here: https://stackoverflow.com/questions/45592405/junit-assertionerror-when-testing-simpledateformat
Thanks in advance. ![]()
答案1
得分: 3
JsonPath操作的是实际的JSON本身。到此时,你的LocalDate已经被转换为JSON的string值。虽然有人会提出,匹配器应该自动将Java值转换为字符串,但实际上它并不会这样做,但如果你调用localDate.toString(),那么它应该可以工作。
(更一般地说,每当你遇到一个匹配器错误,说两个看起来相同的值不匹配,这可能是因为它们是不同类型,但有一个共同的toString()格式。)
英文:
JsonPath operates on actual JSON itself. By this time, your LocalDate has been converted to a JSON string value. While there's an argument that the matcher should automatically convert Java values to strings, it doesn't, but if you call localDate.toString(), then you it should work.
(More generally, any time you get a matcher error saying that two values that look identical don't match, it's probably because they're different types that have a common toString() format.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论