Junit Mockito:Mock一种操作输入参数的方法
以前有人问过这个问题,但我看不到完全相同的问题&当然看不到解决方案 我试图模拟一个数据库Dao调用,该调用将对象保存到数据库中。 Dao调用返回新的PK,但也通过更新PK来修改传递的对象 我的测试正在按我想要的方式工作,除了验证失败,表明我没有通过预期的对象。然而,当我在调试器中暂停时,我可以看到insert确实在接受一个没有PK的对象。然后它正在修改它&调用的控制器可以看到更改的对象Junit Mockito:Mock一种操作输入参数的方法,junit,mockito,Junit,Mockito,以前有人问过这个问题,但我看不到完全相同的问题&当然看不到解决方案 我试图模拟一个数据库Dao调用,该调用将对象保存到数据库中。 Dao调用返回新的PK,但也通过更新PK来修改传递的对象 我的测试正在按我想要的方式工作,除了验证失败,表明我没有通过预期的对象。然而,当我在调试器中暂停时,我可以看到insert确实在接受一个没有PK的对象。然后它正在修改它&调用的控制器可以看到更改的对象 @Test public void insertSampleAnalyteLabConfig() throws
@Test
public void insertSampleAnalyteLabConfig() throws Exception {
int newInt = 99;
SampleAnalyteLabConfig sampleAnalyteLabConfig = createMockSampleAnalyteLabConfig(null);
SampleAnalyteLabConfig sampleAnalyteLabConfig2 = createMockSampleAnalyteLabConfig(null);
when(sampleAnalyteLabConfigService.save(sampleAnalyteLabConfig)).thenAnswer( invocation -> {
SampleAnalyteLabConfig foo = (SampleAnalyteLabConfig) invocation.getArguments()[0];
foo.setId(newInt);
return new Long(newInt);
}
);
mockMvc.perform(post("/api/lab/sampleanalytelab")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(getBytes(sampleAnalyteLabConfig))).andExpect(status().isCreated());
verify(sampleAnalyteLabConfigService, times(1)).save(sampleAnalyteLabConfig2);
}
测试输出如下:
参数不同!通缉:
sampleAnalyteLabConfigService.save(
SampleAnalyteLabConfig{{id=0}sampleId=2,analyteId=3,labId=1,numberOfRounds=null,AbsolutePerformanceCoreWarning=null}
);
->在com.foo.controllers.LabControllerTest.insertSampleAnalyteLabConfig(LabControllerTest.java:236)上
实际调用有不同的参数:
sampleAnalyteLabConfigService.save(
SampleAnalyteLabConfig{{id=99}sampleId=2,analyteId=3,labId=1,numberOfRounds=null,AbsolutePerformanceCoreWarning=null}
);
->位于com.foo.controllers.LabController.saveSampleAnalyteLabConfig(LabController.java:165)
比较失败:
参数不同!通缉:
sampleAnalyteLabConfigService.save(
SampleAnalyteLabConfig{{id=0}sampleId=2,analyteId=3,labId=1,numberOfRounds=null,AbsolutePerformanceCoreWarning=null}
);
->在com.foo.controllers.LabControllerTest.insertSampleAnalyteLabConfig(LabControllerTest.java:236)上
实际调用有不同的参数:
sampleAnalyteLabConfigService.save(
SampleAnalyteLabConfig{{id=99}sampleId=2,analyteId=3,labId=1,numberOfRounds=null,AbsolutePerformanceCoreWarning=null}
);
->位于com.foo.controllers.LabController.saveSampleAnalyteLabConfig(LabController.java:165)
已断开与目标VM的连接,地址:'127.0.0.1:61076',传输:'socket'
当您在或验证时将直接值传递给时,Mockito默认使用Java
equals
。您看到的是,您已经创建了两个独立的SampleAnalyteLabConfig
实例,您正在用一个不同的实例(未修改)传入一个实例(该实例被修改以添加其ID)。假设等于
和hashCode
起作用,只需确保准备要验证的实例,以匹配要比较的修改实例即可
SampleAnalyteLabConfig sampleAnalyteLabConfig = createMockSampleAnalyteLabConfig(null);
SampleAnalyteLabConfig sampleAnalyteLabConfig2 = createMockSampleAnalyteLabConfig(null);
// ...
verify(sampleAnalyteLabConfigService, times(1)).save(sampleAnalyteLabConfig2);
参数不同!需要:sampleAnalyteLabConfigService.save(SampleAnalyteLabConfig{{id=0}sampleId=2,analyteId=3,labId=1,numberOfRounds=null,absolutePerformanceScoreWarning=null});->在com.foo.controllers.LabControllerTest.insertSampleAnalyteLabConfig(LabControllerTest.java:236)上
实际调用有不同的参数:sampleAnalyteLabConfigService.save(SampleAnalyteLabConfig{{id=99}sampleId=2,analyteId=3,labId=1,numberOfRounds=null,absolutePerformanceScoreWarning=null});->位于com.foo.controllers.LabController.saveSampleAnalyteLabConfig(LabController.java:165)
从评论中: 我知道我可以在sampleAnalyteLabConfig2上调用setId(),但这是我的问题,因为save()方法不是用Id集调用的,所以要求verify()确认它是用setId()调用的是错误的 Mockito不负责复制对象:当您使用
verify
检查对象时,您正在检查实例的当前状态,包括在调用服务期间或之后对其所做的任何修改。在考虑对象的三个实例时,记住这一点很重要:您的sampleAnalyteLabConfig
、您的sampleAnalyteLabConfig2
,以及ObjectMapper创建的然后传递到服务中的实例
您所做的验证语句将验证ObjectMapper创建的一个实例的post-save
状态,包括您对foo.setId(newInt)的调用代码>从您的答案中。您没有根据调用期间创建的实例快照进行验证,因为Mockito没有创建快照
一般来说,我认为调用<代码> SETID(NeWTT)<代码>在您的代码> SAMPPLAYTALLATABACTION2中是安全的,并且对它进行测试,因为newInt
是一个唯一的整数,除了您的测试之外,它不太可能来自任何地方:您可以从成功的验证中推断出对象被准确地传入和修改,并且只按照您的预期。我当然会这么做。但是,如果要检查传递到save
的实例的修改前状态,则应删除修改状态的应答或将断言移动到应答中。(您也可以在更改答案中的状态之前克隆该实例,并测试克隆,但除了使用已编写的库或帮助程序在该状态下传递外,这没有多大价值。)默认情况下,Mockito使用Javaequals
,当您将直接值传递到时
或验证时
。您看到的是,您已经创建了两个独立的SampleAnalyteLabConfig
实例,您正在用一个不同的实例(未修改)传入一个实例(该实例被修改以添加其ID)。假设等于
和hashCode
起作用,只需确保准备要验证的实例,以匹配要比较的修改实例即可
SampleAnalyteLabConfig sampleAnalyteLabConfig = createMockSampleAnalyteLabConfig(null);
SampleAnalyteLabConfig sampleAnalyteLabConfig2 = createMockSampleAnalyteLabConfig(null);
// ...
verify(sampleAnalyteLabConfigService, times(1)).save(sampleAnalyteLabConfig2);
参数不同!需要:sampleAnalyteLabConfigService.save(SampleAnalyteLabConfig{{id=0}sampleId=2,analyteId=3,labId=1,numberOfRounds=null,absolutePerformanceScoreWarning=null});->在com.foo.controllers.LabControllerTest.insertSampleAnalyteLabConfig(La
@Test
public void insertSampleAnalyteLabConfig() throws Exception {
int newInt = 99;
SampleAnalyteLabConfig sampleAnalyteLabConfig = createMockSampleAnalyteLabConfig(null);
when(sampleAnalyteLabConfigService.save(sampleAnalyteLabConfig)).thenAnswer( invocation -> {
verify(sampleAnalyteLabConfigService, times(1)).save(sampleAnalyteLabConfig);
SampleAnalyteLabConfig foo = (SampleAnalyteLabConfig) invocation.getArguments()[0];
foo.setId(newInt);
return new Long(newInt);
}
);
mockMvc.perform(post("/api/lab/sampleanalytelab")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(getBytes(sampleAnalyteLabConfig))).andExpect(status().isCreated());
}