断言或模拟验证可重用性 - 错误行

时间:2018-04-26 10:12:49

标签: java junit mockito assertions

我对Mockito进行了很长时间的测试,我希望重用不同参数的验证方法,以便测试代码更加干净和可维护。 像这样。

@Test
public void aggTest() throws ParseException, IOException {

    mockDataLoader();

    // This several times with different dates or hours
    testProcessSamples("2018-01-01 00:00:00 UTC");
    // ...

    // Then verify:     
    verifyDL("HOUR", "OP_DIR", "01/01/2018 00:00:00;ROA_OP-IN-B;;;;;;;;;;;;;;;;;;;");
    verifyDL("HOUR", "OP_DIR", "01/01/2018 00:00:00;ROA_OP-OUT-B;2;2;2;;;2;2;;;;;;;;;;;;");
    verifyDL("DAY", "AGG_DIR", "31/01/2018 00:00:00;ROA_AGG_Z_IN;;;;;;;;;;;;;;;;;;;");
    // About 100 lines like this ...
    verifyDL("MONTH", "AGG_DIR", "01/01/2018 00:00:00;ROA_AGG_Y_IN;;;;;;;;ERROR;;;;;;;;;;;"); // Where the error actually is
    verifyDL("MONTH", "AGG_DIR", "01/01/2018 00:00:00;ROA_AGG_Q_IN;;;;;;;;;;;;;;;;;;;");
    verifyDL("MONTH", "AGG_DIR", "01/01/2018 00:00:00;ROA_AGG_M_IN;;;;;;;;;;;;;;;;;;;");        

    BDDMockito.verifyNoMoreInteractions(dataLoader);
}


private void verifyDL(String gra, String type, String csv) {
    BDDMockito.verify(dataLoader).loadData( // Where JUnit thinks the error is
            BDDMockito.argThat(new ContainsCsv(csv)),
            BDDMockito.argThat(new MatchXml(gra, type)));
}

但是当它失败时,JUnit显然会指向BDDMockito.verify(dataLoader).loadData行作为错误点。我希望它指向测试中的实际行,即verifyDL的调用。

完整的堆栈跟踪在那里,但是我必须在实际值之后滚动并且每次都寻找正确的堆栈层,而不是仅仅点击我IDE上的一个方便的位置才能被带到错误点。

正如您所看到的,我已经制作了自己的匹配器来缩短验证码,但由于可维护性需要,它仍然不能很好地适用于一行。

有没有办法告诉JUnit,verifyDL是一个帮助方法,应该从堆栈中排除?

我需要像宏来编写更少的内容并将其转换为实际的验证码。

测试说明:

我正在嘲笑一个名为dataLoader的低级服务,然后我在更高级别上运行一些处理一些输入文件的东西,并且深度调用dataLoader将被多次调用。

毕竟,我检查对dataLoader的调用是否包含了预期包含的数据。

修改

我尝试了这种方法,但我仍然想在测试中选择参数顺序,这是我可以用verifyDL辅助方法做的事情:

vDL().loadData(argCsv("31/01/2018 23:00:00;AGG_XXXX_OUT;2;2;1;;;2;1;;;;;;;;;;;;"), argXml("HORA", "AGG_DIR"));
vDL().loadData(argCsv("31/01/2018 23:00:00;AGG_Y_OUT;2;2;1;;;2;1;;;;;;;;;;;;"), argXml("HORA", "AGG_DIR"));
vDL().loadData(argCsv("31/01/2018 23:00:00;AGG_ZZZZZZZZZZZ_OUT;;;;;;;;;;;;;;;;;;;"), argXml("HORA", "AGG_DIR"));
vDL().loadData(argCsv("31/01/2018 00:00:00;AGG_XXXX_OUT;2;2;1;;;2;1;;;;;;;;;;;;"), argXml("DIA", "AGG_DIR"));
vDL().loadData(argCsv("31/01/2018 00:00:00;AGG_Y_OUT;2;2;1;;;2;1;;;;;;;;;;;;"), argXml("DIA", "AGG_DIR"));
vDL().loadData(argCsv("31/01/2018 00:00:00;AGG_ZZZZZZZZZZZ_OUT;;;;;;;;;;;;;;;;;;;"), argXml("DIA", "AGG_DIR"));     
vDL().loadData(argCsv("01/01/2018 00:00:00;AGG_XXXX_OUT;5;8;7;;;8;7;;;;;;;;;;;;"), argXml("MES", "AGG_DIR"));
vDL().loadData(argCsv("01/01/2018 00:00:00;AGG_Y_OUT;5;8;7;;;8;7;;;;;;;;;;;;"), argXml("MES", "AGG_DIR"));
vDL().loadData(argCsv("01/01/2018 00:00:00;AGG_ZZZZZZZZZZZ_OUT;;;;;;;;;;;;;;;;;;;"), argXml("MES", "AGG_DIR")); 

1 个答案:

答案 0 :(得分:1)

也许最简单的方法就是抓住Mockito抛出的异常并重新抛出一个带有更详细消息的新异常。像这样......

@Test
public void execute_test(){
    verifyExecution("First test case","one", "two");
}


public void verifyExecution(String description, String parameter_one, String parameter_two) {
    try {
        BDDMockito.verify(mockedService).doIt(eq(parameter_one), eq(parameter_one));
    } catch (MockitoAssertionError e) {
        throw new MockitoAssertionError(String.format("Verification failed while testing case %s, with message:\n%s", description, e.getMessage()));
    }
}

这会将'description'参数添加到Mockito生成的消息中。通过这种方式,您可以获得Mockito提供的所有信息并添加到您正在测试的场景中。