Search code examples
unit-testingmstestassert

Multiple Asserts in a Unit Test


I've just finished reading Roy Osherove's "The Art of Unit Testing" and I am trying to adhere to the best practices he lays out in the book. One of those best practices is to not use multiple asserts in a test method. The reason for this rule is fairly clear to me, but it makes me wonder...

If I have a method like:

public Foo MakeFoo(int x, int y, int z)
{
     Foo f = new Foo();
     f.X = x;
     f.Y = y;
     f.Z = z;

     return f;
}

Must I really write individual unit tests to assert each separate property of Foo is initialized with the supplied value? Is it really all that uncommon to use multiple asserts in a test method?

FYI: I am using MSTest.

EDIT: Thanks for all the responses. I think I'll wind up going with the multiple asserts. In my situation the behavior being tested is that MakeFoo makes a proper Foo. So asserting that each property is getting the expected value should suffice. However, if there was a condition around setting one of the properties then I'd test each of the individual outcomes separately.

I still don't like it though.... The reason I like the idea of having one assert per test is that you know the exact reason a test failed. If you fix the problem then the test will pass. With multiple asserts you don't have the same guarantee. If you fix the problem alluded to by the failing assertion, there is nothing to stop another assertion later on in the test from failing next. If the asserts were split up, then you'd have known about both failures from the start.

And finally, the reason I'm not just using .Equals() is because in my situation Foo is a LINQ-To-SQL entity which introduces some complications that aren't worth getting into here.

Thank again.


Solution

  • It is far more important to test just one concept per unit test.

    It may take more than one assertion to test a concept, so don't worry overly about the number of assertions. Of course if you end up with a large number of assertions, you may want to take a step back and think about what you are really testing.