0

這是現在部分3在series PowerMockito不匹配重載的方法...當返回類型不同

我(還)試圖檢查bar(Alpha, Baz)使用PowerMockito(bar(Xray, Baz)private)稱爲bar(Xray, Baz) - 而實際上並沒有打電話給後面的人,下面給出我的MCVE類Foo。需要注意的是bar(Alpha, Baz)回報什麼,而其他兩個返回String,而且我知道我should也許測試的富工程,而不是如何 ...

public class Foo { 
    private String bar(Xray xray, Baz baz) { return "Xray"; } 

    private String bar(Zulu zulu, Baz baz) { return "Zulu"; } 

    public void bar(Alpha alpha, Baz baz) { // this one returns nothing 
     if(alpha.get() instanceof Xray) { 
      System.out.println(bar((Xray) alpha.get(), baz)); 
      return; 
     } else if(alpha.get() instanceof Zulu) { 
      System.out.println(bar((Zulu)alpha.get(), baz)); 
      return; 
     } else { 
      return; 
     } 
    } 
} 

用戶kswaughs solved the issue爲私有重載方法,當所有方法具有相同的返回類型時。而elsewhere有人建議使用when()方法與Method對象。不過,現在我已經定義了bar(Alpha, Baz)使用不同的返回類型形成的其他方法,都再次分開下降:

@RunWith(PowerMockRunner.class) 
public class FooTest { 

    @Test 
    public void testBar_callsBarWithXray() throws Exception { 
     Baz baz = new Baz(); //POJOs 
     Alpha alpha = new Alpha(); 
     alpha.set(new Xray()); 

     Foo foo = new Foo(); 
     Foo stub = PowerMockito.spy(foo); 

     Method m = Whitebox.getMethod(Foo.class, "bar", Xray.class, Baz.class); 

     PowerMockito.doReturn("ok").when(stub, m); 

     stub.bar(alpha, baz); // fails here - even though that then calls stub.bar(Xray, Baz); 

     // Testing if bar(Xray, Baz) was called by bar(Alpha, Baz) 
     PowerMockito.verifyPrivate(stub, times(5)).invoke("bar", any(Xray.class), any(Baz.class)); 
    } 
} 

異常其所有美麗:

org.mockito.exceptions.base.MockitoException: 
'bar' is a *void method* and it *cannot* be stubbed with a *return value*! 
Voids are usually stubbed with Throwables: 
    doThrow(exception).when(mock).someVoidMethod(); 
*** 
If you're unsure why you're getting above error read on. 
Due to the nature of the syntax above problem might occur because: 
1. The method you are trying to stub is *overloaded*. Make sure you are calling the right overloaded version. 
2. Somewhere in your test you are stubbing *final methods*. Sorry, Mockito does not verify/stub final methods. 
3. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - 
    - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method. 

    at FooTest.testBar_callsBarWithXray(FooTest.java:31) 

使用.withArguments(any(Xray.class), any(Baz.class))似乎沒有區別。

雖然點亮,但例外不幸的是不能告訴如何讓我的設置實現點1。有任何想法嗎?

+0

我認爲你錯過了@PrepareForTest(Foo.class)類類型的註釋 –

回答

0

這裏,問題不在於不同的返回類型,它只與重載的方法有關。使用MemberMatcher.method()代替WhiteBox.getMethod, 出於測試目的,在公共小節方法的頂部添加了sysout語句。

public void bar(Alpha alpha, Baz baz) { // this one returns nothing 

System.out.println("public bar"); 

if(alpha.get() instanceof Xray) { 
    System.out.println(bar((Xray) alpha.get(), baz)); 
    return; 
} else if(alpha.get() instanceof Zulu) { 
    System.out.println(bar((Zulu)alpha.get(), baz)); 
    return; 
} else { 
    return; 
} 
} 

下面是測試方法,當我們使用MemberMatcher時,PrepareForTest是Foo.class所必需的。

@Test 
public void testBar_callsBarWithXray() throws Exception { 
    Baz baz = new Baz(); //POJOs 
    Alpha alpha = new Alpha(); 
    alpha.set(new Xray()); 

    Foo stub = PowerMockito.spy(new Foo()); 

    Method m = MemberMatcher.method(Foo.class, 
       "bar", 
       Xray.class, Baz.class); 

    PowerMockito.doReturn("ok") 
     .when(stub, m) 
     .withArguments(Matchers.any(Xray.class), Matchers.any(Baz.class)); 

    stub.bar(alpha, baz); 

    PowerMockito.verifyPrivate(stub, Mockito.times(1)).invoke("bar", Matchers.any(Xray.class), Matchers.any(Baz.class)); 
    // Mockito's equivalent for a public method: verify(stub, times(1)).bar(any(Xray.class), any(Baz.class)); 
} 

output is : 
public bar 
ok