简体   繁体   中英

Mock object method by calling another object's method with the first one's arguments?

I just want to do this:

Mockito.when(methodOne.read(Mockito.any(byte[].class)).
thenReturn(methodTwo.read(***The argument methodOne was called with (aka whatever was Mockito.any(byte[].class))***));

Specifically, I have an inputstream that reads into a byte[] array. However, this inputstream cannot be read from during unit testing, so I need to mock this by reading from another inputstream that I will hardcode some values. This other input stream should also read into the byte[] array. Any way to do this?

I tried the below but it gives me a weird error message: error: incompatible types: no instance(s) of type variable(s) T exist so that Answer conforms to byte[]:

Mockito.when(inStreamOne.read(Mockito.any(byte[].class))).then(inStreamTwo.read(returnsFirstArg()));

The problem

You received error message:

no instance(s) of type variable(s) T exist so that Answer<T> conforms to byte[]

The argument to method then (which is an alias for thenAnswer ) must be of type Answer<?>

  • returnsFirstArg() is an Answer<T> that looks at the invocation and returns the first argument (inferring the return type)
  • you cannot pass returnsFirstArg() to inStreamTwo.read() . Answer<T> will never become byte[] , no matter what T is inferred. This is the meaning of the error message.

Solution

You must create your own instance of Answer<Integer>

  • take the first argument ( byte[] )
  • call read on the underlying stream
  • return the result of read
var buffer = new byte[4];
Mockito.when(inputStreamOne.read(Mockito.any(byte[].class)))
       .thenAnswer(invocation -> {
           byte[] buf = invocation.getArgument(0);
           return sourceInputStream.read(buf);
       });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM