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

huangapple go评论72阅读模式
英文:

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() 方法对 GenericDatumWriterBufferedBinaryEncoderEncoderFactory 进行模拟,但是对我来说都没有起作用。

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&lt;T&gt; datumWriter = new GenericDatumWriter&lt;&gt;(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(&quot;&quot;, 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&lt;T&gt; datumWriter = new GenericDatumWriter&lt;&gt;(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&lt;YourClass&gt; datumWriter = Mockito.mock(DatumWriter&lt;YourClass&gt;.class);
    when(datumWriter.write(anyObject(), anyObject())).thenThrow(IOException.class);
    
    serializer.setDatumWriter(datumWriter);  
   
    serializer.serialize(&quot;&quot;, avroObject);
}

huangapple
  • 本文由 发表于 2020年9月8日 15:52:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63789449.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定