简体   繁体   English

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

[英]How to unit test when a function calls another function returning a boolean?

Below is an code which I need to unit test. 下面是我需要进行单元测试的代码。 I would write 2 unit test cases for getFoo , one for true(x==5) and other for false(x==10) . 我会为getFoo编写2个单元测试用例,一个用于true(x==5) ,另一个用于false(x==10) My question is do I need to write two unit test functions even for convertWrapper for true and false case ? 我的问题是,即使对于true和false情况,即使是convertWrapper我也需要编写两个单元测试函数吗? In my opinion I should, to ensure that in future someone does not cause a change in convertWrapper, resulting in regression. 我认为,应该确保将来不会有人在convertWrapper中造成更改,而导致回归。 But just wondering whats considered a widely adopted practice in such cases. 但是,只是想知道在这种情况下什么被认为是广泛采用的做法。

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

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

One option: ensure convertWrapper calls and returns the result of getFoo, and unit test getFoo. 一种选择:确保convertWrapper调用并返回getFoo的结果,并对getFoo进行单元测试。

Mocks help do integration tests like that. 模仿者可以帮助进行集成测试。

Best practice is to write unit tests in general. 最佳实践是一般编写单元测试。 They should be simple and easy to maintain. 它们应该简单易维护。 If using multiple tests methods is the simplest and easiest to maintain do that. 如果使用多种测试方法是最简单,最容易维护的方法。 In general, I try not to write too much boiler plate code in unit tests. 通常,我尽量不要在单元测试中写太多样板代码。

Ask yourself - what is the general contract of convertWrapper . 问问自己convertWrapper的一般合同是convertWrapper If it's to return true for a particular input, and return false for any other input, then test that it does that. 如果要为特定输入返回true,并为其他任何输入返回false,则测试它是否可以这样做。 The fact that it is implemented via getFoo is irrelevant to how you'll unit test it. 它通过getFoo实现的事实与您如何对其进行单元测试无关。

If somebody in the future changes the implementation so that it still returns true or false for the same inputs as before, but doesn't use getFoo then that should NOT break the test. 如果将来有人更改实现,以便对于与以前相同的输入仍返回true或false,但不使用getFoo则不应破坏测试。

Since getFoo is public, it should have its own tests. 由于getFoo是公共的,因此它应该具有自己的测试。

Yes, you probably do want to write separate cases, because your opinion is generally correct and is precisely the type of situation proper testing is meant to avoid: 是的,您可能确实希望编写单独的案例,因为您的意见通常是正确的,而恰恰是正确测试旨在避免的情况类型:

In my opinion I should, to ensure that in future someone does not cause a change in convertWrapper, resulting in regression. 我认为,应该确保将来不会有人在convertWrapper中造成更改,而导致回归。

Your unit tests should test the high-level functionality of your code. 单元测试应该测试代码的高级功能。 Your unit tests are unaware of implementation details, they only test that the terms of the "contract" are met. 您的单元测试不了解实现细节,它们仅测试是否符合“合同”的条款。 Since you have two public methods that, on a high level, do two separate things (we presume - your requirements weren't stated or documented), then you have two separate tests. 由于您有两种可以在较高层次上执行两项独立工作的公共方法(我们假设-您的要求没有陈述或记录),因此您有两项单独的测试。

Eliminating one of the tests because you, as the developer, implicitly know that the implementations are the same suddenly brings information about implementation details into the testing realm, which is asking for problems and regressions in the future. 因为您(作为开发人员)隐式地知道实现是相同的,所以消除了其中一项测试,这突然将有关实现详细信息的信息带到了测试领域,这将在将来引起问题和退化。

One option that Dave Newton pointed out in his answer is to write a unit test that essentially ensures that convertWrapper(ch) == getFoo((int)ch) for all relevant ch . Dave Newton在他的答案中指出的一个选择是编写一个单元测试,该测试实质上确保所有相关ch convertWrapper(ch) == getFoo((int)ch) That is a fine suggestion and may very well be appropriate, but only if the high level requirement of convertWrapper is that it "returns the same value as getFoo ". 这是一个很好的建议,可能非常合适,但convertWrapperconvertWrapper高级要求是“返回与getFoo相同的值”。 Again, your tests should reflect your requirements. 同样,您的测试应反映您的要求。

Of course, that doesn't mean it's somehow against the law to eliminate the test. 当然,这并不意味着消除测试在某种程度上是违法的。 The devil won't necessarily lay claim to your soul if you do it (although sometimes I wish that was the usual consequence). 如果您这样做,魔鬼不一定会向您的灵魂求婚(尽管有时我希望那是通常的后果)。 If your application is rather simple, or if you are willing to accept the associated risks, then even a simple "@todo Test me" documentation marker may be enough to get by. 如果您的应用程序很简单,或者您愿意承担相关的风险,那么即使是简单的“ @todo Test me”文档标记也足够了。 It is sometimes OK to take shortcuts now and then but only if you truly understand and accept the implications -- only you can save you from yourself. 有时可以时不时地使用快捷方式, 但前提是您必须真正理解并接受其中的含义 -只有您才能从自己身上救出来。 :) :)

But, in the general case, yes, two tests. 但是,在一般情况下,是的,有两个测试。 Then you can "fire-and-forget" your tests, and never have to remember that special exception to the rules you made in the future. 然后,您可以“解雇”您的测试,而不必记住将来您制定的规则的特殊例外。

Why do you think you need to write only two unit tests for getFoo ? 为什么您认为只需要为getFoo编写两个单元测试?

Of course, you know that the method really can only go one of two ways, but the caller doesn't. 当然,您知道该方法实际上只能采用以下两种方法之一,而调用者则不能。 It might seem ridiculous with a method this trivial, but you need to think in terms of the contract for the method. 使用这种琐碎的方法看似荒谬,但您需要考虑该方法的合同问题。 Maybe you need to test with 5, then 0, then a negative number, then a really high positive number, or whatever other weird case a caller expects you to be able to handle. 也许您需要测试5、0,一个负数,然后一个非常高的正数,或者呼叫者希望您能够处理的其他任何奇怪的情况。

Similar with convertWrapper . convertWrapper相似。 You know it calls getFoo and getFoo has really only two paths, but you can't let yourself think that way. 您知道它调用getFoogetFoo实际上只有两条路径,但是您不能让自己这么想。

The bottom line is you need to define the contract for your methods and run enough tests where you feel confident that your public methods satisfy that contract. 最重要的是,您需要为您的方法定义合同,并在确信自己的公共方法满足该合同的情况下运行足够的测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 单元测试android:当调用另一个函数返回并使用时,如何返回函数不为null - Unit test android: How to return function not to be null when calls another function return and use 返回布尔函数和另一个函数 - Returning boolean function with another function Mockito - 如果参数设置在另一个 function 调用的 function 中,如何进行单元测试 - Mockito - how to unit test if argument is set in a function called by another function 如何编写返回布尔值的私有函数的JUnit测试? - How can I write a JUnit test of a private function which is returning a Boolean? 如何使用Mockito测试以静态值作为参数从中调用另一个void函数的函数 - How to test function which calls another void function from it with static value as argument using mockito function 的单元测试将调用另一个具有动态值的 function - Unit Test for function that will call another function with dynamic values 如何通过顺序调用测试void函数 - How to test a void function with sequential calls A function 未在单元测试中执行 - A function is not executed in an unit test 如何为 Azure Function TimerTrigger 实现单元测试 - How to implement unit test for Azure Function TimerTrigger 如何更正我的GCD功能单元测试 - How to correct my unit test for GCD function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM