-1

I'm trying to create a test where the third request will throw an error and validate the input of the previous ones.

@Test
void sample() throws IOException {
    var is = spy(new ByteArrayInputStream(new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));
    doReturn(3, 3, 3)
            .doThrow(new IOException("FOO"))
            .when(is)
            .read(any());
    byte[] buf = new byte[3];
    assertThat(is.read(buf)).isEqualTo(3);
    assertThat(buf).isEqualTo(new byte[]{0,1,2});
}

What I got was

expected: [0, 1, 2]
 but was: [0, 0, 0]

Is this a limitation of Mockito spy or is there something I am missing.

Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265

1 Answers1

-1

Since I want the normal behaviour, there's actually a doCallRealMethod() Stubber that can be used instead of having to return the value which will update the buffer as expected.

  @Test
  void validateSpyByteInputStream() throws IOException {
    var is = spy(new ByteArrayInputStream(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));
    doCallRealMethod()
        .doCallRealMethod()
        .doCallRealMethod()
        .doThrow(new IOException("FOO"))
        .when(is)
        .read(any(byte[].class));
    byte[] buf = new byte[3];
    assertThat(is.read(buf)).isEqualTo(3);
    assertThat(buf).isEqualTo(new byte[] {0, 1, 2});
    assertThat(is.read(buf)).isEqualTo(3);
    assertThat(buf).isEqualTo(new byte[] {3, 4, 5});
    assertThat(is.read(buf)).isEqualTo(3);
    assertThat(buf).isEqualTo(new byte[] {6, 7, 8});
    assertThatThrownBy(() -> is.read(buf)).isInstanceOf(IOException.class).hasMessage("FOO");
  }
Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265