0

Ce fait maintenant partie 3 dans un series ...PowerMockito ne correspond pas à la méthode de surcharge lorsque les types de retour diffèrent

Je suis (encore) essayer de vérifier si bar(Alpha, Baz) appelé bar(Xray, Baz) en utilisant PowerMockito (bar(Xray, Baz) est private) - sans réellement appeler le plus tard, étant donné ma classe MCVE Foo ci-dessous. Notez que rien bar(Alpha, Baz) de retour, tandis que les deux autres String retour, et que je suis au courant que je should peut-être test pour que Foo fonctionne, au lieu de comment ...

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; 
     } 
    } 
} 

utilisateur kswaughs solved the issue pour méthodes privées surchargées, lorsque toutes les méthodes ont le même type de retour. Et elsewhere il a été suggéré d'utiliser la méthode when() avec un objet Method ... Cependant, maintenant que je l'ai défini bar(Alpha, Baz) d'utiliser un autre type de retour forment les autres méthodes, tout se écroule à nouveau:

@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)); 
    } 
} 

L'exception dans toute sa beauté:

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) 

l'utilisation .withArguments(any(Xray.class), any(Baz.class)) ne semble pas faire une différence.

Tandis que sur place, l'exception ne dit malheureusement pas comment rendre le point 1 devenu réalité avec la configuration que j'ai. Des idées?

+0

Je pense qu'il vous manque l'anotation de type de classe @PrepareForTest (Foo.class) –

Répondre

0

Ici, le problème n'est pas avec différents types de retour, il est seulement avec des méthodes surchargées. Utilisez MemberMatcher.method() au lieu de WhiteBox.getMethod, À des fins de test, Ajout de l'instruction sysout en haut de la méthode de la barre publique.

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; 
} 
} 

est inférieure à la méthode d'essai, PrepareForTest est nécessaire pour Foo.class lorsque nous utilisions MemberMatcher.

@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