英文:
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.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论