使用EclEMMA的捕获块的代码覆盖率

时间:2015-04-02 06:23:52

标签: java testing junit mockito eclemma

我有catch块,我想执行catch块。我的班级文件是,

    public class TranscoderBean implements TranscoderLocal {
    public byte[] encode(final Collection<?> entitySet) throws TranscoderException {
        Validate.notNull(entitySet, "The entitySet can not be null.");
        LOGGER.info("Encoding entities.");
        LOGGER.debug("entities '{}'.", entitySet);

        // Encode the Collection
        MappedEncoderStream encoderStream = null;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            // Create the encoder and write the the DSE Logbook messgae
            encoderStream = new MappedEncoderStream(outputStream, this.encoderVersion);
            encoderStream.writeObjects(new ArrayList<Object>(entitySet), false);
            encoderStream.flush();
        }
        catch (Exception e) {
            LOGGER.error("Exception while encoding entities", e);
            throw new TranscoderException("Failed to encode entities", e);
        }
        finally {
            if (encoderStream != null) {
                try {
                    encoderStream.close();
                }
                catch (IOException e) {
                    LOGGER.error("Exception while closing the endcoder stream.", e);
                    throw new TranscoderException("Failed to close encoder stream", e);
                }
            }
        }
     }

我的测试类文件是,

public class TranscoderBeanTest {

    private TranscoderBean fixture;

    @Mock
    MappedEncoderStream mappedEncoderStream;
    @Test
    public void encodeTest() throws TranscoderException {
        List<Object> entitySet = new ArrayList<Object>();
        FlightLog log1 = new FlightLog();
        log1.setId("F5678");
        log1.setAssetId("22");

        FlightLog log2 = new FlightLog();
        log2.setId("F5679");
        log2.setAssetId("23");
        entitySet.add(log1);
        entitySet.add(log2);

        MockitoAnnotations.initMocks(this);
        try {
            Mockito.doThrow(new IOException()).when(this.mappedEncoderStream).close();

            Mockito.doReturn(new IOException()).when(this.mappedEncoderStream).close();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        byte[] encode = this.fixture.encode(entitySet);
        Assert.assertNotNull(encode);
    } 
}

我已经尝试过,Mockito.doThrow和Mockito.doReturn方法,但仍然没有执行catch块。出了什么问题。

3 个答案:

答案 0 :(得分:0)

要测试try-catch块,可以使用TestNG方法,该方法包括使用以下注释expectedExceptions实现测试方法。 这个方法的代码,你必须实现它才能引发这个异常,所以catch块将被执行。

您可以查看http://testng.org/doc/documentation-main.html#annotations

答案 1 :(得分:0)

您确定自己拥有合适的测试课程吗?我在你的

中没有看到对TranscoderBean的任何引用

答案 2 :(得分:0)

你希望Mockito做一些它不声称要做的事情:

Mockito.doThrow(new IOException()).when(this.mappedEncoderStream).close();

此声明断言,只要有人在mapperEncoderStream-Object上调用close(),就会收到IOException。你永远不会打电话给close

尝试在Mockito操作后添加mapperEncoderStream.close();并输入catch块 - 但请注意:这不会帮助您解决问题,因为mockito无法帮助您。

对于您的问题,您可以考虑以下替代方案:

重写

encoderStream = new MappedEncoderStream(outputStream, this.encoderVersion);

encoderStream = createMappedEncoderStream(outputStream);

MappedEncoderStream createMappedEncoderStream(ByteArrayOutputStream outputStream) {
  return new MappedEncoderStream(outputStream, this.encoderVersion);
}

这允许您将模拟注入依赖项。

然后按照以下方式初始化你的固定:

fixture = new TranscoderBean() {
  MappedEncoderStream createMappedEncoderStream(ByteArrayOutputStream outputStream) {
    return mappedEncoderStream; //this is your mock
  }
}

这会将mock注入TranscoderBean.encode方法。

然后更改模拟注释:

@Mock(answer=CALLS_REAL_METHODS)
MappedEncoderStream mappedEncoderStream;

这是必需的,因为您的编码方法不仅会在close上调用mappedEncoderStream,还会调用writeObjectsflush。这些调用可能会抛出异常,因此必须通过调用真实对象来模拟或替换它们。

像那样修剪你的测试

@Test(expected=TranscoderException.class)
public void encodeTest() throws TranscoderException {
    //... same as above
    MockitoAnnotations.initMocks(this);
    Mockito.doThrow(new IOException()).when(this.mappedEncoderStream).close();

     this.fixture.encode(entitySet); //this will throw an exception
}

执行以下操作:

  • 编码方法不返回null!它会抛出TranscoderException,因此会将其设置为expected
  • 覆盖close方法,但抛出异常
  • call encode