views:

106

answers:

4

Hi,

I hope this doesn't come across as a stupid question but its something I have been wondering about. I wish to write unit test a method which contains some logic to check that certain values are not null.

public void MyMethod(string value1, string value2)
{
    if(value1 != null)
    {
     //do something (throw exception)
    }

    if(value2 != null)
    {
     //do something (throw exception)
    }

    //rest of method
}

I want to test this by passing null values into the method. My question is should I create a unit test for each argument or can I create one unit test which checks what happens if I set value1 to null and then checks what happens if I set value2 to null.

i.e.

[TestMethod]
public void TestMyMethodShouldThrowExceptionIfValue1IsNull()
{
    //test
}

[TestMethod]
public void TestMyMethodShouldThrowExceptionIfValue2IsNull()
{
    //test
}

or

[TestMethod]
public void TestMyMethodWithNullValues()
{
  //pass null for value1
  //check

  //pass null for value2
  //check
}

Or does it make any difference? I think I read somewhere that you should limit yourself to one assert per unit test. Is this correct?

Thanks in advance Zaps

+7  A: 

You should write a unit test for each test case (assertion) to avoid Assertion Roulette.

Mark Seemann
+2  A: 

If you are doing two tests in the same test method, your tests are not doing "unit-test".

For instance, what if the test for the first null value fails ?
If both tests are in the same test method, the second test will probably not be executed ; which means the test on the second null value depends on the test on the first null value.

On the other hand, if you have two separate test methods, you can test each case in perfect isolation.


Judging from the code of your MyMethod method, there is no link between the two conditions ; which means there shouldn't probably be any dependancy between the tests for those two conditions.

So : you should use two distinct tests.

Pascal MARTIN
Even if you group your tests, your unit of code under test is still the same - so it's still unit test no matter what :o) But what you gradually lose is ability to pinpoint the failure. In practice it's trade-off between a lot of tests(=a lot of syntax) vs ability to pinpoint - see Michael's answer.
MaR
+3  A: 

The "ideal" unit test test one thing only in order to pinpoint errors exactly.

In practice, this is not nearly as important as most TDD proponents state, because tests don't fail frequently, and finding out which assert failed takes almost no time compared with the rest of the work involved in investigating and fixing the problem.

Doing extra work when writing the tests to save yourself work when it fails (which may never happen) is a form of YAGNI.

If having multiple methods is no extra work beyond typing more method declarations, you should do it, but if it leads to duplicated setup code, I see absolutely nothing wrong with testing several conditions in one test method.

Michael Borgwardt
A: 

To extrapolate to a non-technical thought.

Say you have a car, and you want to test the color.

Tests might be:

Car is red. Car is blue. Car is painted.

Now it might make sense to have "Painted" and "blue", but they really are different things. And if you test red and blue, it will always fail - or the failure would not make sense from an isolation standpoint.

Always test ONE thing at a time as you suggest, and many things comprise the test suite.

Mark Schultheiss