2015-12-29 17 views
6

Mój scenariusz jest całkiem prosty. Próbujesz użyć częściowych mumów, zgodnie z ostatnią odpowiedzią na temat samych siebie. Mój test jest:Mockito Spy - częściowe kpiny nie działają?

@Test 
public void test() { 
    ClassUnderTest realObject = new ClassUnderTest(); 
    ClassUnderTest spy = spy(realObject); 
    when(spy.methodB()).thenThrow(new Exception("Testing")); 

    spy.methodA(); 
} 

a klasa badany jest:

import org.apache.commons.lang3.NotImplementedException; 

public class ClassUnderTest { 

    int methodB(){ 
     throw new NotImplementedException("Not implemented"); 
    } 

    public int methodA(){ 
     methodB(); 
     return 0; 
    } 

} 

Spodziewam się, że mój przedmiot szpiegostwo nazwałbym metoda B podnoszenie „testing” wyjątek podczas gdy faktycznie prawdziwa metoda jest wywoływana rzucając wyjątek "Nie zaimplementowany". Zachowuje się tak, jakbym nie miał częściowego, pozorowanego zachowania w tym miejscu.

Dlaczego tak jest? czego mi brakuje?

EDIT: Jak sugeruje RPresle, próbowałem przy użyciu składni

doThrow(new Exception("Testing")).when(spy.methodB()); 

Jednak dostaję UnfinishedStubbingException:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here: 
-> at SimpleTest.test(SimpleTest.java:15) 

E.g. thenReturn() may be missing. 
Examples of correct stubbing: 
when(mock.isOk()).thenReturn(true); 
when(mock.isOk()).thenThrow(exception); 
doThrow(exception).when(mock).someVoidMethod(); 
Hints: 
1. missing thenReturn() 
2. you are trying to stub a final method, you naughty developer! 
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed 

at SimpleTest.test(SimpleTest.java:15) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

ktoś może dostarczyć więcej wskazówek?

+2

Zrobiłeś '.Przy (spy.methodB());' natomiast RPresle napisał '.Przy (szpieg) .methodB();' – QBrute

+0

Masz rację. Dziękuję Ci bardzo. Czy uważasz, że powinienem usunąć moją edycję, czy moja "literówka" mogłaby być użyteczna dla przyszłych czytelników? –

Odpowiedz

9

Nawiązując do this tutorial na Mockito, widać, że Mockito wywołuje oryginalną metodę.

Jest tylko jedno zastrzeżenie do tej składni. Prawdziwa metoda rule.createFileTemplate() zostanie wywołana tylko raz. Może to mieć wiele skutków ubocznych i może nawet zawieść, rzucając wyjątek (bardzo często NPE). Aby rozwiązać ten problem, można (? Powinno) użyć tej alternatywnej Mockito składnię:

doReturn(mockFileTemplate).when(rule).createFileTemplate(); 

Aby tego uniknąć należy użyć innej składni Mockito doReturn().when()

doThrow(new Exception("Testing")).when(spy).methodB(); 

nadzieję, że to pomaga.

EDIT:

Proszę zauważyć, że struktura jest trochę inna niż when().thenReturn().

doThrow(new Exception("Testing")) 
    .when(spy) 
    .methodB(); 
+0

Dziękuję bardzo za odpowiedź. Sprawdź moje edytowane pytanie ... –