Java >> Java-zelfstudie >  >> Tag >> return

Mockito - verschil tussen doReturn() en when()

De twee syntaxis voor stubbing zijn ongeveer gelijk. U kunt echter altijd gebruik doReturn/when voor stoten; maar er zijn gevallen waarin u niet kunt gebruik when/thenReturn . Stubbing void-methoden zijn er zo een. Anderen zijn gebruik met Mockito-spionnen en meerdere keren op dezelfde methode stoten.

Een ding dat when/thenReturn geeft je die doReturn/when doet, is typecontrole van de waarde die u retourneert, tijdens het compileren. Ik geloof echter dat dit bijna geen waarde heeft - als je het type verkeerd hebt, kom je erachter zodra je je test uitvoert.

Ik raad ten zeerste aan om alleen doReturn/when te gebruiken . Het heeft geen zin om twee syntaxis te leren als er één voldoende is.

Je zou kunnen verwijzen naar mijn antwoord op Forming Mockito "grammatics" - een meer gedetailleerd antwoord op een zeer nauw verwante vraag.


Beide benaderingen gedragen zich anders als je een bespioneerd object gebruikt (geannoteerd met @Spy ) in plaats van een mock (geannoteerd met @Mock ):

  • when(...) thenReturn(...) maakt een echte methode-aanroep net voordat de opgegeven waarde wordt geretourneerd. Dus als de aangeroepen methode een Exception genereert, moet je ermee omgaan / het bespotten enz. Natuurlijk krijg je nog steeds je resultaat (wat je definieert in thenReturn(...) )

  • doReturn(...) when(...) roept de methode helemaal niet aan .

Voorbeeld:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

Test:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");

De Mockito javadoc lijkt te vertellen waarom doReturn() . wordt gebruikt in plaats van when() Gebruik doReturn() in die zeldzame gevallen waarin u Mockito.when(Object) niet kunt gebruiken.

Pas op dat Mockito.when(Object) altijd wordt aanbevolen voor stubbing, omdat het type-veilig en leesbaarder is (vooral bij het afstoten van opeenvolgende oproepen).

Dit zijn de zeldzame gevallen waarin doReturn() van pas komt:

1. Wanneer het bespioneren van echte objecten en het aanroepen van echte methoden op een spion bijwerkingen heeft

List list = new LinkedList(); List spy = spy(list);

//Impossible:echte methode wordt zo genoemd spy.get(0) throwsIndexOutOfBoundsException (de lijst is nog leeg)

when(spy.get(0)).thenReturn("foo");

//Je moet doReturn() gebruiken voor stubbing:doReturn("foo").when(spy).get(0);

2. Een eerdere uitzonderingsstubbing overschrijven:

when(mock.foo()).thenThrow(new RuntimeException());

//Onmogelijk:de exception-stubbed foo() methode heet soRuntimeException wordt gegooid. when(mock.foo()).thenReturn("bar");

//Je moet doReturn() gebruiken voor stubbing:

doReturn("bar").when(mock).foo(); Bovenstaande scenario's laten een afweging zien van de elegante syntaxis van Mockito. Merk op dat de scenario's echter zeer zeldzaam zijn. Spionage zou sporadisch moeten zijn en het overheersen van uitzonderingen is zeer zeldzaam. Om nog maar te zwijgen over het feit dat het overschrijven van stubbing in het algemeen een mogelijke codegeur is die wijst op te veel stubbing.


Java-tag