英文:
mockito getAllValues on captured arguments replaces all invocation args with the last invocation
问题
以下是您的代码段的中文翻译部分:
在我的代码中,我有以下内容:
kiteOrderService.modifyOrder(params, profitBracketOrder.getOrder().orderId);
还有另一个地方的调用。通过调试,我已经验证了第一次调用的params.price
为525,而第二次调用为475。但在测试代码中:
verify(mockKiteOrderService, times(2)).modifyOrder(orderParamsArgumentCaptor.capture(), eq("3"));
List<OrderParams> orderParamsCaptured = orderParamsArgumentCaptor.getAllValues();
assertThat(orderParamsCaptured.get(0).price).isEqualTo(525.0);
assertThat(orderParamsCaptured.get(1).price).isEqualTo(475.0);
orderParamsCaptured.get(0).price
为475,这是两次调用都捕获的值。
在我的build.gradle
中,我没有指定任何mockito依赖项,我有:
testImplementation ('org.junit.vintage:junit-vintage-engine'){
exclude group: 'org.hamcrest', module :'hamcrest-core'
}
我也尝试添加:
testImplementation group: 'org.mockito', name: 'mockito-core', version: '5.3.1'
但没有任何区别。我不知道正在使用哪个mockito版本,我粘贴了我的build.gradle
如下:
dependencies {
implementation ('org.springframework.boot:spring-boot-starter-web')
implementation group: 'com.google.truth', name: 'truth', version: '1.1.3'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation ('org.junit.vintage:junit-vintage-engine'){
exclude group: 'org.hamcrest' , module :'hamcrest-core'
}
}
这可能是相关的。我的测试不是一个Spring Boot测试,而是一个普通的JUnit5单元测试,具有以下注解:
@ExtendWith(MockitoExtension.class)
希望这有所帮助。
英文:
In my code I have
kiteOrderService.modifyOrder(params, profitBracketOrder.getOrder().orderId);
and another invocation at another place. Via stepping through I have verified that the first invocation params.price is 525 and for the second it is 475. Yet in the test code
verify(mockKiteOrderService, times(2)).modifyOrder(orderParamsArgumentCaptor.capture(), eq("3"));
List<OrderParams> orderParamsCaptured = orderParamsArgumentCaptor.getAllValues();
assertThat(orderParamsCaptured.get(0).price).isEqualTo(525.0);
assertThat(orderParamsCaptured.get(1).price).isEqualTo(475.0);
orderParamsCaptured.get(0).price is 475 and this is the value captured for both invocations.
In my build.gradle I didn't have any mockito dependency specified, I have
testImplementation ('org.junit.vintage:junit-vintage-engine'){
exclude group: 'org.hamcrest' , module :'hamcrest-core'
}
I have also tried adding
testImplementation group: 'org.mockito', name: 'mockito-core', version: '5.3.1'
but it didn't make any difference. I don't know which mockito version is getting used, I'm pasting my build.gradle below:
dependencies {
implementation ('org.springframework.boot:spring-boot-starter-web')
implementation group: 'com.google.truth', name: 'truth', version: '1.1.3'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation ('org.junit.vintage:junit-vintage-engine'){
exclude group: 'org.hamcrest' , module :'hamcrest-core'
}
}
that may be relevant. My test is not a spring boot test but a normal Junit5 unit test has has the annotation
@ExtendWith(MockitoExtension.class)
Any help is much appreciated.
答案1
得分: 0
你没有将价格传递给您的方法,并且价格没有被捕获。您传递了对“OrderParams”实例的引用。如果稍后修改此实例,则更改将反映在捕获的引用中。“ArgumentCaptor”不会奇迹般地复制其捕获的对象,它们只保留对它的引用。
这是一个简化的示例:
final Service svc = mock(Service.class);
final Params captor = ArgumentCaptor.forClass(Params.class);
final Params params = new Params();
params.setPrice(42);
svc.process(params);
verify(svc).process(captor.capture());
params.setPrice(1337); // 这会更改捕获的引用!
assertEquals(1337, captor.getValue().getPrice());
这与Mockito或ArgumentCaptors无关,而是与Java的工作方式有关。
必读:https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
英文:
You are not passing the price to your method and the price is not captured. You are passing a reference to an OrderParams
instance. If you modify this instance later, the changes will be reflected in the captured reference. ArgumentCaptor
s do not magically copy their captured objects, they only keep a reference to it.
Here's a simplified example:
final Service svc = mock(Service.class);
final Params captor = ArgumentCaptor.forClass(Params.class);
final Params params = new Params();
params.setPrice(42);
svc.process(params);
verify(svc).process(captor.capture());
params.setPrice(1337); // this changes the captured reference!
assertEquals(1337, captor.getValue().getPrice());
This has nothing to do with Mockito or ArgumentCaptors, but the way Java works.
Must-read: https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
答案2
得分: 0
我发现为每个验证创建一个单独的ArgumentCaptor并以某种方式正确捕获了参数。
英文:
I found that creating a separate Argumentcaptor to use for each verification somehow captures the arguments correctly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论