我正在更改身份策略,并且使用的是在将实体写入数据库之前生成的ID。由于我们模拟某些服务调用的方式,此更改导致我们的某些测试失败。
TimeLog timeLog = buildTimeLog('123456', mockEmployeeId);
TimeLog mockTimeLog = buildTimeLog('123456', mockEmployeeId);
when(this.timeLogService.save(mockTimeLog)).thenReturn(timeLog);
当测试调用Controller时,Controller中绑定的实体将获得与预期的模拟不同的ID,因为该实体会生成该ID。以前,数据库会生成ID,因此模拟程序可以正常工作。
是否有一种方法可以告诉Mockito忽略期望中的某个属性?这样可以解决问题,并且测试仍然有效。否则,欢迎使用其他方法。
答案 0 :(得分:1)
您不能告诉Mockito忽略期望中的属性,因为它使用的是Java的“等于”方法...您可以在TimeLog中定义一个等于ID的equals方法,但我怀疑这样做不会给您带来什么想。另一种方法是,与其尝试告诉嘲笑未验证的内容,不如使用hamcrest匹配器明确定义要验证的内容。定义一个仅与您要验证的字段(即ID以外的所有其他字段)匹配的hamcrest匹配器。像这样:
private class TimeLogMatcher extends TypeSafeMatcher<TimeLog> {
private final EmployeeId employeeId;
public TimeLogMatcher(EmployeeId employeeId) {
this.employeeId = employeeId;
}
@Override
public void describeTo(Description description) {
description.appendText("TimeLog with employeeId=" + employeeId);
}
@Override
public boolean matchesSafely(TimeLog item) {
return employeeId.equals(item.getEmployeeId());
}
}
然后不调用您的“ buildTimeLog”方法正在调用的Mockito Matchers类,例如:
TimeLog timeLog = Matchers.argThat(new TimeLogMatcher(mockEmployeeId));
或者,您也可以始终使用Answer对象:
when(this.timeLogService.save(any(TimeLog.class)).thenAnswer(new Answer<TimeLog> {
public TimeLog answer(InvocationOnMock invocation) throws Throwable {
TimeLog receivedTimeLog = invocation.getArgumentAt(0, TimeLog.class);
assertThat(receivedTimeLog.getEmployeeId(), equalTo(mockEmployeeId));
return timeLog;
}
});
这一切有意义吗?