[英]Mockito Spying on Class that has an internal method reference
在使用@Spy注釋監視服務並讓Mockito創建顯式調用構造函數的Server詩句時,我發現行為有所不同。
public class MyService {
private final Supplier<String> methodBCall;
public MyService() {
methodBCall = this::methodB;
}
public void methodA() {
methodBCall.get();
}
public String methodB() {
return "methodB";
}
}
@RunWith(MockitoJUnitRunner.class)
public class MyTest {
@Spy
private MyService myService1;
@Spy
private MyService myService2 = new MyService();
@Test
public void testSucceeds() {
myService1.methodA();
verify(myService1, times(1)).methodA();
verify(myService1, times(1)).methodB();
}
@Test
public void testFails() {
myService2.methodA();
verify(myService2, times(1)).methodA();
verify(myService2, times(1)).methodB();
}
}
測試失敗的原因是
Wanted but not invoked:
myService2.methodB();
-> at com.phemi.services.policy.impl.MyTest.testFails
為什么這兩個行為不同? Mockito在初始化myService1使其能夠監視methodB時在做什么?
這是一個簡化的示例,在本例中,為了正確測試我的服務,我需要使用參數調用其構造函數(因此不能將@Spy與默認構造函數一起使用)。 但是,當我這樣做時,我無法正確驗證方法調用。
的spy
上myService2
對象已經被構造之后,所以具有在一個方法調用時才創建constructor
並不有益的,因為它包含的方法參照初始對象(其不是spy
對象)。
當您比較兩種情況的實現時,差異變得更加明顯:
public static <T> T spy(Class<T> classToSpy) {
return MOCKITO_CORE.mock(classToSpy, withSettings()
.useConstructor()
.defaultAnswer(CALLS_REAL_METHODS));
}
public static <T> T spy(T object) {
return MOCKITO_CORE.mock((Class<T>) object.getClass(), withSettings()
.spiedInstance(object)
.defaultAnswer(CALLS_REAL_METHODS));
}
如您所見,第一種情況基於一個類(如果未創建@Spy
實例,則使用@Spy
),首先創建一個模擬並在模擬對象上使用構造函數。
在第二種情況下,不考慮構造函數,而是創建了一個不同的實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.