【发布时间】:2023-03-27 23:27:01
【问题描述】:
我编写了一个长除法应用程序,现在我想对其进行测试。 稍微简化一下,我有:Classes simplified
- InputData 类包含两个长整数:被除数和除数。 InputData 实例提供给 Division。
- 创建实例除法后,我对其运行 divide() 方法以生成 OutputData。
- OutputData 包含有关除法过程的每个阶段的所有信息以及结果的元数据(整数与否、周期性与否等)
- 最后 OutputData 是我要测试的 printer.print() 的输入。
问题是如何正确使用mocks\stubs\spies来测试printer类的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 将包含 List 每个包含 5 个字段。 outputData
我有点明白如何为此使用 spy(),但如果我理解正确 spy() 运行实际方法,那么依赖关系仍然存在,并且无法实现完全隔离。那为什么我的测试版本更差?
【问题讨论】:
-
您不需要 Mockito、InputData、Division 来测试以 OutputData 和 OutputStream 作为参数的 Printer 方法。您只需要一台打印机、一个OutputData 和一个OutputStream。创建打印机和输出数据应该很简单。关于流,最简单的方法是使用一个 ByteArrayOutputStream,调用方法,将流转换为字节数组,看看它是否包含预期的字节。
-
是的,这就是我使用 streamOut 的方式,它是一个 ByteArrayOutputStream。但是如何创建 OutputData?它应该看起来像这样prntscr.com/ijh959
-
new OutputData(the, required, arguments)? IE。与您在 Division.divide() 方法中创建它的方式相同。 -
所需的参数不是微不足道的,如prnt.sc/ijh959 所示,它们是在divide() 中计算的。我应该在纸上进行计算然后手动创建 allStages 变量吗?但即便如此,它也将依赖于 Stage() 类。
-
您可以使用 Division 类来创建一个 OutputData,如果它可以让您的测试变得更简单。核心点是 Mockito 是无关紧要的。使用 ByteArrayOutputStream 作为参数调用您的打印方法,并检查是否已写入预期的字节。
标签: java unit-testing junit mockito