2016-05-02 12 views
3

Beim Debugging stieß ich mit Mockito 1.10 auf etwas sehr merkwürdiges. Ich hatte gehofft, dass jemand das hier wahrgenommene Verhalten erklären könnte:Warum verhält sich Mockito mit InputStreams seltsam?

Wenn ich Folgendes ausführe, hängt mein Thread und mein Test kehrt nie zurück. Die CPU des erstellten Java-Prozesses wird ebenfalls astronomisch!

@Test(expected = IOException.class) 
public void nonMockitoExpected() throws IOException { 
    final InputStream mis = new InputStream() { 

     @Override 
     public int read() throws IOException { 
      throw new IOException(); 
     } 
    }; 
    ByteStreams.copy(mis, new ByteArrayOutputStream()); 
} 

Jede Hilfe zu verstehen, wie und warum die Mockito Methode versagt wäre fantastisch:

@Test(expected = IOException.class) 
public void mockitoWeirdness() throws IOException { 
    final InputStream mis = mock(InputStream.class); 
    doThrow(IOException.class).when(mis).read(); 
    ByteStreams.copy(mis, new ByteArrayOutputStream()); 
} 

Wenn ich diese Methode manuell Stummel wie folgt, wird der erwartete IOException geworfen.

+0

Ich weiß nicht 'ByteStreams.copy' Implementierung, aber vielleicht ruft es nicht' read() 'das liest ein Byte, sondern ruft' read (byte []) ' –

+0

Ich vermute, dass' ByteStreams.copy() ' ruft vor dem read() etwas anderes auf dem InputStream auf. Wäre sehr hilfreich, wenn wir diesen Code der Klasse hätten, um weiter zu untersuchen. – Ray

+0

ByteStreams ist die GoogleGuava-Bibliothek dafür. Ich denke, Sie sind hier beide richtig. Wenn ich die Klasse ausspioniere, ist das Verhalten erfolgreich. Ich werde noch genauer untersuchen, welche Methode das ist. –

Antwort

2

Wenn Sie sich die ByteStreams Implementierung ansehen, können Sie sehen, dass die read (buf) Methode verwendet wird. In Ihrem Fall gibt es Null zurück, weil es keine Scheindefinition dafür gibt und dies eine Endlosschleife in der Kopie Methode verursacht.

Sie können entweder die default mock behaviour ändern oder manuell eine Definition für die Methode lesen (buff) hinzufügen.

1

Sie wollen werden Ihre Mock einzurichten die wirklichen Methoden der InputStream zu nennen, wenn man sie nicht gerodet haben

final InputStream mis = Mockito.mock(InputStream.class, Mockito.CALLS_REAL_METHODS); 

Die javadoc Staaten

Diese Implementierung kann hilfreich sein bei der Arbeit mit altem Code. Wenn diese Implementierung verwendet wird, werden unstubbed-Methoden an die reale Implementierung delegieren. Dies ist eine Möglichkeit, ein partielles Mock-Objekt zu erstellen, das standardmäßig echte Methoden aufruft.

Mockito, standardmäßig Mocks alles. Die zuerst verwendete Methode ByteStreams#copy ruft InputStream#read(byte[]) auf. Da Mockito es verspottet hat, wird es 0 zurückgeben, welches ByteStreams#copy interpretiert als "es gibt mehr zu lesen von diesem Strom" und weiter liest (Endlosschleife).

Mit der Verwendung von Mockito.CALLS_REAL_METHODS, sagen Sie Mockito die tatsächliche Implementierung in InputStream aufrufen, die an read() delegieren wird, die Sie eine Ausnahme auszugeben stubbed haben.

Verwandte Themen