【发布时间】:2020-09-08 07:52:07
【问题描述】:
我写了一个avro序列化的方法,我想测试一下。
方法
@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
// need to mock here
// 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());
但问题又回到了,我应该如何将这些对象传递给我的序列化程序,同时牢记最佳实践?
【问题讨论】:
-
请参阅minimal reproducible example。 “我试过了”......但是你的代码在哪里做呢?!嘲笑的重点是:你需要知道你在做什么。你没有告诉我们你到底做了什么,那么你希望我们告诉你什么?
-
除此之外,我觉得真正的答案是:你应该退后一步,真正研究如何使用这些模拟框架。您可能听说过“好吧,我可以模拟事物”,但似乎还没有人告诉您:模拟对象以某种方式需要传递给您的生产代码,以便实际调用它们。换句话说:单独的模拟框架是没有意义的。您必须学习如何编写可测试的代码,以便您可以轻松使用这样的框架,从而获得体面的生产和测试代码。
-
@GhostCat 同意你的观点。我已经习惯于在 Python 中进行单元测试时修补类,这是我在 Java 中无法做到的(或者我可以做到吗?)......那么你有什么建议?有一个
DatumWriter的设置器对我来说看起来像是糟糕的代码。 -
@GhostCat 添加了我尝试过的内容。
-
有多种方法可以到达那里。一种方法:有一个(非公共)构造函数,将该对象作为参数(除非该对象已设置为某个 ctor 参数)。或者,还有 InjectMocks 注释。这确实有一些魔力,但问题是当它注入失败时你不会得到任何错误。回到我的观点:这不是你可以根据 5 分钟的反馈 stackoverflow 获得的东西。如果你想用 java 和 mockito 做真正的工作,你必须硬着头皮坐上一两天,学习如何正确地做事。
标签: java serialization junit mockito avro