如何隔离void print()方法进行测试

时间:2018-02-25 12:07:56

标签: java unit-testing junit mockito

我写了一个长除法应用程序,我现在要测试它。 稍微简化一下,我有:Classes simplified

  1. 包含两个long的InputData类:dividend和divisor。 InputData实例提供给Division。
  2. 创建实例除法后,我在其上运行divide()方法以生成OutputData。
  3. OutputData包含有关除法过程的每个阶段和结果元数据的所有信息(整数与否,周期与否等)
  4. 最后,OutputData是printer.print()的输入,我想测试它。
  5. printer output

    问题是如何正确使用mocks \ stubs \ spies来测试打印机类的void print方法?我的老师说我不能有任何变量,除了outputData和OutputStream来测试打印机并建议阅读有关mockito的内容。

    我想说我想用这些输入测试打印机输出的正确性:-943和225.我的非隔离版本看起来像这样:

    @Test
    void testPrintDivisionNegativePositiveRecurrentExpansion() {
        final long VALID_INPUT_DIVIDEND = -943;
        final long VALID_INPUT_DIVISOR = 225;
        inputData = new InputData(VALID_INPUT_DIVIDEND, VALID_INPUT_DIVISOR);
        Division division = new Division(inputData);
        OutputData outputData = division.divide();
        printer.print(outputData, streamOut);
        String actual = streamOut.toString();
        String expected = "_-943|225\r\n" + " -900|--------\r\n" + " ----|-4.19(1)\r\n" + " _-430\r\n" + "  -225\r\n"
                + "  ----\r\n" + " _-2050\r\n" + "  -2025\r\n" + "  -----\r\n" + "   _-250\r\n" + "    -225\r\n"
                + "    ----\r\n" + "     -25\r\n";
        assertEquals(expected, actual);
    }
    

    我读过有关模拟和存根的内容,但大多数示例建议使用when()。then()并返回简单的字符串或int,而在我的情况下,outputData将包含每个包含5个字段的Lis​​t。 outputData

    我有点看到我如何使用spy(),但是如果我理解正确spy()运行实际方法,那么依赖仍然存在并且不会实现完全隔离。那为什么我的测试版本更糟?

1 个答案:

答案 0 :(得分:1)

您在测试中的代码是什么?

这是你必须回答的最重要的问题。

任何其他类都有自己的代码与之交互的业务逻辑应该被模拟。

从您的测试名称我想,printer对象是您正在测试的代码,而OutputData是一个依赖项(为您的测试用例提供)不相关的业务逻辑。所以你应该嘲笑:

class MyTestClass {
  @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); 
  @Mock OutputData outputData;
  @Test
  void testPrintDivisionNegativePositiveRecurrentExpansion() {
    // configure mock of OutputData
    printer.print(outputData, streamOut);
    String actual = streamOut.toString();
    String expected = "_-943|225\r\n" + " -900|--------\r\n" + " ----|-4.19(1)\r\n" + " _-430\r\n" + "  -225\r\n"
        + "  ----\r\n" + " _-2050\r\n" + "  -2025\r\n" + "  -----\r\n" + "   _-250\r\n" + "    -225\r\n"
        + "    ----\r\n" + "     -25\r\n";
    assertEquals(expected, actual);
  }
}
  

我读到了关于模拟和存根的内容,但是大多数示例建议使用when()。then()并返回简单的字符串或int,而在我的情况下,outputData将包含每个包含5个字段的Lis​​t。

当您的返回类型很复杂或List时,模拟没有太大区别。您创建它的实例并配置您的模拟以返回:

class MyTestClass {
  @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); 
  @Mock OutputData outputData;
  @Test
  void testPrintDivisionNegativePositiveRecurrentExpansion() {
    List<YourElementType> inputData= Arrays.asList(new YourElementType(dummyValues1), new YourElementType(dummyValues2), new YourElementType(dummyValues3)); 
    doReturn(inputData).when(outputData).getValuesToPrint();
    printer.print(outputData, streamOut);
    // ...