It's recognized that "One Assertion Per Test" in assertion. It is not good to write assertion like below:
Assert((foo != null) && (bar != null));
The better chocie is:
Assert(foo != null);
Assert(bar != null);
The question is what if the assertion is:
Assert((foo == null) || (foo.length == 0));
The relationship is OR instead of AND.
Is there any way to make "One Assertion per test" while keep the logic?
The idea behind the guideline is that you only test one logical thing (which may boil down to a few asserts in some cases) in one test. Therefore if a test fails, you know the exact reason why it failed and can zone in into the specific block of code in a snap. To borrow an example from this page, if the following test fails, I know something is wrong with how country is extracted/determined in the Address type.
public void testCountry() throws Exception {
assertEquals("COUNTRY", anAddress.getCountry());
}
Compare this with the version of the test with multiple asserts, it could fail for multiple reasons (and unless you use helpful assert messages) you'd need to debug the test (yuck!).
I'd need to see your complete test. From what it see, it seems to be that you're checking a collection for a something-not-found scenario. In which case, the recommendation is to return an empty collection so that the clients don't have to check for null. Since your test is also a client, it's life is also made simpler : Assert.AreEqual (0, foo.length)
The problem could not in the assertion, but in the Arrange or Act part of the testcase: when you unit-test, you invoke a [small] piece of code in a controlled environment. That is to say that you should know how the software under test will behave, and thus, know whether it will return a null pointer, or an empty string. Every test shall have one expected result.
... Unless you're using your test against several functions/methods that behave differently, or some third-party code that appears to behave differently in different situations. If this is the case, the "One assertion per rule" is just a guideline, and you can use the assertion as shown is the question. If this test fails, it will mean that the returned foo is a non-empty string.
Or, you could create a function to test for empty strings that will also test if the string pointer is not null:
Assert(is_empty_string(foo));
Your language string class may provide this method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With