英文:
Mockito | JUnit | Avro: Mocking a void method does not work
问题
方法
@SneakyThrows
@Override
public byte[] serialize(String topic, T data) {
try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
writeSerializedAvro(stream, data, data.getSchema());
return stream.toByteArray();
} catch (IOException e) {
throw new AvroSerializationException(e.getMessage(), e);
}
}
private void writeSerializedAvro(ByteArrayOutputStream stream, T data, Schema schema) throws IOException {
binaryEncoder = EncoderFactory.get().binaryEncoder(stream, binaryEncoder);
DatumWriter<T> datumWriter = new GenericDatumWriter<>(schema);
datumWriter.write(data, binaryEncoder);
binaryEncoder.flush();
}
datumWriter.write
或者 binaryEncoder.flush()
可能会抛出 IOException
。
在测试中,我希望看到是否会抛出 IOException
,我的方法会捕捉它并将其包装在 AvroSerializationException
中(这是我编写的一个类)。
单元测试
@Test(expected = AvroSerializationException.class)
public void testSerializeException() throws IOException {
// Given
// 需要在这里进行模拟
// When
serializer.serialize("", avroObject);
}
我已经尝试过使用 doThrow().when()
方法对 GenericDatumWriter
、BufferedBinaryEncoder
和 EncoderFactory
进行模拟,但是对我来说都没有起作用。
BufferedBinaryEncoder binaryEncoder = Mockito.mock(BufferedBinaryEncoder.class);
Mockito.doThrow(new IOException()).when(binaryEncoder).flush();
以及
GenericDatumWriter datumWriter = Mockito.mock(GenericDatumWriter.class);
Mockito.doThrow(new IOException()).when(datumWriter).write(any(), any());
但是问题又回到了,根据最佳实践,我应该如何将这些对象传递给我的序列化器呢?
英文:
I wrote a method for avro serialization, which I want to test.
Method
@SneakyThrows
@Override
public byte[] serialize(String topic, T data) {
try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
writeSerializedAvro(stream, data, data.getSchema());
return stream.toByteArray();
} catch (IOException e) {
throw new AvroSerializationException(e.getMessage(), e);
}
}
private void writeSerializedAvro(ByteArrayOutputStream stream, T data, Schema schema) throws IOException {
binaryEncoder = EncoderFactory.get().binaryEncoder(stream, binaryEncoder);
DatumWriter<T> datumWriter = new GenericDatumWriter<>(schema);
datumWriter.write(data, binaryEncoder);
binaryEncoder.flush();
}
datumWriter.write
or binaryEncoder.flush()
can throw IOException
.
In the test, I want to see if IOException
is thrown, my method catchers it and wraps it in AvroSerializationException
(a class written by me).
Unit Test
@Test(expected = AvroSerializationException.class)
public void testSerializeException() throws IOException {
// Given
// need to mock here
// When
serializer.serialize("", avroObject);
}
I have tried mocking GenericDatumWriter
, BufferedBinaryEncoder
and EncoderFactory
with doThrow().when()
methods but nothing worked for me.
BufferedBinaryEncoder binaryEncoder = Mockito.mock(BufferedBinaryEncoder.class);
Mockito.doThrow(new IOException()).when(binaryEncoder).flush();
And
GenericDatumWriter datumWriter = Mockito.mock(GenericDatumWriter.class);
Mockito.doThrow(new IOException()).when(datumWriter).write(any(), any());
But again, the question comes back to, how am I supposed to pass these objects to my serializer, keeping the best practices in mind?
答案1
得分: 1
你需要首先使用Mockito来模拟对象,并在你的类中使用它,然后异常将会被抛出,就像下面这样:
你的代码:
private DatumWriter<T> datumWriter = new GenericDatumWriter<>(schema);
@SneakyThrows
@Override
public byte[] serialize(String topic, T data) {
try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
writeSerializedAvro(stream, data, data.getSchema());
return stream.toByteArray();
} catch (IOException e) {
throw new AvroSerializationException(e.getMessage(), e);
}
}
private void writeSerializedAvro(ByteArrayOutputStream stream, T data, Schema schema) throws IOException {
binaryEncoder = EncoderFactory.get().binaryEncoder(stream, binaryEncoder);
datumWriter.write(data, binaryEncoder);
binaryEncoder.flush();
}
public void setDatumWriter (DatumWriter datumWriter){
this.datumWriter=datumWriter;
}
你的测试代码:
@Test(expected = AvroSerializationException.class)
public void testSerializeException() throws IOException {
// Given
DatumWriter<YourClass> datumWriter = Mockito.mock(DatumWriter<YourClass>.class);
when(datumWriter.write(anyObject(), anyObject())).thenThrow(IOException.class);
serializer.setDatumWriter(datumWriter);
serializer.serialize("", avroObject);
}
英文:
You need first to mock the object using Mockito and use it in your class and then the exception will be thrown, like below:
Your code:
private DatumWriter<T> datumWriter = new GenericDatumWriter<>(schema);
@SneakyThrows
@Override
public byte[] serialize(String topic, T data) {
try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
writeSerializedAvro(stream, data, data.getSchema());
return stream.toByteArray();
} catch (IOException e) {
throw new AvroSerializationException(e.getMessage(), e);
}
}
private void writeSerializedAvro(ByteArrayOutputStream stream, T data, Schema schema) throws IOException {
binaryEncoder = EncoderFactory.get().binaryEncoder(stream, binaryEncoder);
datumWriter.write(data, binaryEncoder);
binaryEncoder.flush();
}
public void setDatumWriter (DatumWriter datumWriter){
this.datumWriter=datumWriter;
}
Your test code:
@Test(expected = AvroSerializationException.class)
public void testSerializeException() throws IOException {
// Given
DatumWriter<YourClass> datumWriter = Mockito.mock(DatumWriter<YourClass>.class);
when(datumWriter.write(anyObject(), anyObject())).thenThrow(IOException.class);
serializer.setDatumWriter(datumWriter);
serializer.serialize("", avroObject);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论