【问题标题】:Code Coverage for Catch Blocks using EclEMMA使用 EclEMMA 的 Catch 块的代码覆盖率
【发布时间】:2015-04-02 06:23:52
【问题描述】:

我有 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 块。做错了什么。

【问题讨论】:

    标签: java testing junit mockito eclemma


    【解决方案1】:

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

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

    【讨论】:

    【解决方案2】:

    你确定你有正确的测试类。我在您的

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

    【讨论】:

    • 为了将来参考,这种回复最好作为对原始问题的评论。
    • Mockito.doThrow(new IOException()).when(this.mappedEncoderStream).close();
    【解决方案3】:

    您希望 Mockito 做它没有声称做的事情:

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

    此语句断言,每当有人在 mapperEncoderStream-Object 上调用 close() 时,都会收到一个 IOException。你永远不会打电话给close

    尝试在您的 Mockito-actions 之后添加 mapperEncoderStream.close();,然后将输入 catch 块 - 但请注意:这不会帮助您解决问题,因为 mockito 在这里无法提供帮助。

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

    重写

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

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

    这使您可以将模拟作为依赖项注入。

    然后像这样初始化你的fixture:

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

    这会将模拟注入到您的 TranscoderBean.encode 方法中。

    然后改变你的模拟注解:

    @Mock(answer=CALLS_REAL_METHODS)
    MappedEncoderStream mappedEncoderStream;
    

    这是必需的,因为您的编码方法不仅在mappedEncoderStream 上调用close,而且还调用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
    }
    

    执行以下操作:

    • encode 方法不返回null!它抛出一个TranscoderException,所以它被放置为expected
    • 用异常抛出覆盖 close 方法
    • 调用编码

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      相关资源
      最近更新 更多