当函数调用返回布尔值的另一个函数时如何进行单元测试?

时间:2013-11-15 02:03:51

标签: java unit-testing

下面是我需要进行单元测试的代码。我会为getFoo编写2个单元测试用例,一个用于true(x==5),另一个用于false(x==10)。 我的问题是,对于真假案例,我是否需要为convertWrapper编写两个单元测试函数?在我看来,我应该确保将来某人不会导致convertWrapper发生变化,导致回归。但只是想知道在这种情况下被广泛采用的做法是什么。

public boolean getFoo(int x) {
    return x == 5;
}

public boolean convertWrapper(char ch) {
    int x = (int)ch;
    return getFoo(x);
}

5 个答案:

答案 0 :(得分:2)

一个选项:确保convertWrapper调用并返回getFoo的结果,并返回单元测试getFoo。

模拟有助于进行类似的集成测试。

答案 1 :(得分:2)

最佳做法是编写单元测试。它们应该简单易维护。如果使用多个测试方法是最简单和最容易维护的方法。一般来说,我尽量不在单元测试中写太多锅炉板代码。

答案 2 :(得分:2)

问问自己 - convertWrapper的一般合同是什么。如果要为特定输入返回true,并为任何其他输入返回false,则测试它是否执行此操作。它是通过getFoo实现的,这与您对其进行单元测试无关。

如果将来有人更改了实现,以便它仍然像以前一样对输入返回true或false,但是不使用getFoo那么这不应该破坏测试。

由于getFoo是公开的,因此它应该有自己的测试。

答案 3 :(得分:1)

是的,您可能确实想要编写单独的案例,因为您的意见通常是正确的,而且恰恰是正确测试旨在避免的情况类型:

  

在我看来,我应该确保将来有人不这样做   导致convertWrapper发生变化,导致回归。

您的单元测试应该测试代码的高级功能。您的单元测试不了解实施细节,他们只测试是否符合“合同”的条款。由于你有两个公共方法,在高层次上做两件事(我们假设 - 你的要求没有说明或记录),那么你有两个单独的测试。

消除其中一个测试,因为作为开发人员,您隐含地知道实现是相同的,突然将实现细节的信息带入测试领域,这将在未来询问问题和回归。

Dave Newton在他的回答中指出的一个选择是编写一个单元测试,基本上确保所有相关convertWrapper(ch) == getFoo((int)ch)的{​​{1}}。这是一个很好的建议,可能非常合适,但前提是ch的高级要求是“返回与convertWrapper相同的值”。同样,您的测试应该反映您的要求。

当然,这并不意味着以某种方式违反法律来消除测试。如果你这样做,魔鬼不一定会声称你的灵魂(虽然有时我希望这是通常的结果)。如果您的应用程序相当简单,或者您愿意接受相关风险,那么即使是简单的“@todo Test me”文档标记也可能足以让您顺利通过。有时可以立即使用快捷方式但只有当您真正理解并接受其含义时 - 只有您可以自己保存。 :)

但是,在一般情况下,是的,两次测试。然后你就可以“发射并忘记”你的测试,而且永远不必记住你将来制定的规则的特殊例外。

答案 4 :(得分:0)

为什么您认为只需为getFoo编写两个单元测试?

当然,您知道该方法实际上只能采用两种方式之一,但调用者不会。使用这种微不足道的方法可能看起来很荒谬,但你需要根据方法的契约来思考。也许你需要测试5,然后是0,然后是负数,然后是一个非常高的正数,或者调用者期望你能够处理的任何其他奇怪的情况。

convertWrapper类似。你知道它调用getFoogetFoo实际上只有两条路径,但你不能让自己这么想。

最重要的是,您需要为您的方法定义合同,并运行足够的测试,以确保您的公共方法满足该合同。