I have a method which puts InputStream in s3 bucket.
@Override
public String putObject(@NonNull String s3BucketName, @NonNull String s3Key, @NonNull String content,
@NonNull ObjectMetadata metadataRequest) {
InputStream stream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
try {
stream.mark(stream.available());
} catch (IOException e) {
String errorMessage = String.format("Runtime error while marking stream.",
s3BucketName, s3Key);
throw new RuntimeException(errorMessage, e);
}
PutObjectRequest request = new PutObjectRequest(s3BucketName, s3Key, stream, metadataRequest);
return putObject(request);
}
I want to make the method cause IOException and then throw RuntimeException and I have written the unit test for the same.
@Test
public void putObjectTest_withStringContent_withMetadataRequest_IOError() {
ObjectMetadata metadataRequest = new ObjectMetadata();
metadataRequest.addUserMetadata(TEST_METADATA_KEY, TEST_METADATA_VALUE);
InputStream mockStream = Mockito.mock(InputStream.class);
Mockito.when(mockStream.mark(mockStream.available())).thenThrow(IOException.class);
assertThrows(RuntimeException.class, () -> s3Accessor.putObject
(TEST_S3BUCKET, TEST_S3OBJECT, TEST_STRING, metadataRequest));
}
This is what I have tried but this is showing error in editor
Required type:
T
Provided:
void
reason: no instance(s) of type variable(s) T exist so that void conforms to T
How can I make the method throw IOException?
CodePudding user response:
stream
is a ByteArrayInputStream
. That will never ever ever throw any exception when mark is called. The documentation clearly states that no IOException
can be thrown, and that the argument is ignored.
Declare stream
to be a ByteArrayInputStream
, and you don't need to catch the IOException
. In fact, you'll get a compiler error:
exception java.io.IOException is never thrown in body of corresponding try statement
CodePudding user response:
stream.mark(...)
will never throw any checked exceptions anyway so this is rather pointless. You also don't need to mark the stream 99% of the time so not sure why you're doing that.
However for reference purposes, Mockito.when(...).thenThrow(...)
is for method invocations that return a value.
stream.mark(mockStream.available())
is a method invocation that does not return a value (void return type).
As per docs:
Use doThrow() when you want to stub the void method with an exception.
In this case, replace:
Mockito.when(mockStream.mark(mockStream.available())).thenThrow(IOException.class);
With:
doThrow(IOException.class).when(mockStream).mark(mockStream.available());