简体   繁体   English

莫基托 | JUnit | Avro:模拟 void 方法不起作用

[英]Mockito | JUnit | Avro: Mocking a void method does not work

I wrote a method for avro serialization, which I want to test.我写了一个avro序列化的方法,我想测试一下。

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 . datumWriter.writebinaryEncoder.flush()可以抛出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).在测试中,我想看看是否IOException ,我的方法捕获它并将其包装在AvroSerializationException (我编写的一个类)中。

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.我曾尝试使用doThrow().when()方法doThrow().when() GenericDatumWriterBufferedBinaryEncoderEncoderFactory ,但没有任何效果对我doThrow().when()

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?但是,问题又回到了,我应该如何将这些对象传递给我的序列化程序,同时牢记最佳实践?

You need first to mock the object using Mockito and use it in your class and then the exception will be thrown, like below:您需要首先使用 Mockito 模拟对象并在您的类中使用它,然后将抛出异常,如下所示:

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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