views:

638

answers:

4

Me and a colleague are starting a new project and attempting to take full advantage of TDD. We're still figuring out all the concepts around unit testing and are thus far basing them primarily on other examples.

My colleague recently brought into question the point of the NUnit syntax helpers and I'm struggling to explain their benefit (since I don't really understand it myself other than my gut says they're good!). Here is an example assertion:

Assert.That(product.IsValid(), Is.False);

To me this makes complete sense, we're saying we expect the value of product.IsValid() to be false. My colleague on the other hand would prefer us to simply write:

Assert.That(!product.IsValid());

He says to him this makes more sense and he can read it easier.

So far the only thing we can agree on is that you are likely to get more helpful output when the test is failing from the former, but I think there must be a better explanation. I've looked up some information on the syntax helpers (http://nunit.com/blogs/?p=44) and they make sense, but I don't fully understand the concept of constraints other than they 'feel' right.

I wonder if someone could explain why we use the concept of constraints, and why they improve the unit test examples above?

Thanks.

+3  A: 

I think it's mostly to do with the pure English reading of the statement.

The first reads

Assert that product is valid is false

The second reads

Assert that not product is valid

I personally find the first easier to process. I think it's all down to preference really. Some of the extension methods out there are interesting though that let you do you assertions like this:

product.IsValid().IsFalse();
Garry Shutler
That's pretty much my opinion of the syntax helpers as well, I'm more looking for the purpose of the underlying constraints. Or are they there for the same reason and the syntax helpers are just an improvement?
roryf
I quite like syntax helpers since they make the assertions sound like a sentence. However, I'm quite comfortable with the normal syntax and so find no reason to force anyone else to use the syntax helpers.
mezoid
I don't think the underlying constraints are changed at all really. It's just a syntactic difference.
Garry Shutler
I didn't mean they were changed, I was wondering what their purpose was irrespective of the syntax helpers.
roryf
Well the reason is the perceived readability. Now whether it is an improvement or not is a matter of opinion.
Garry Shutler
That explains a lot then, time to go eat humble pie :)
roryf
+1  A: 

I can see your version being better than your colleagues. However, I'd still be at least as comfortable with:

Assert.IsFalse(product.IsValid());

If you can convince me that the Assert.That syntax has an objective benefit over the above, I'd be very interested :) It may well just force of habit, but I can very easily read the "What kind of assertion are we making? Now what are we asserting it about?" style.

Jon Skeet
A good point, perhaps the problem is we're using the wrong assertions. To be fair it was copied from elsewhere so I was just following convention :)
roryf
@Rory: I've seen people using Assert.That for cases just like this before, so it's definitely not just you. I don't think there's a "wrong" way - I'd just like to know the benefit of Assert.That in this case, if there is one.
Jon Skeet
+1  A: 

It's all sugar. Internally they're converted to constraints.

From Pragmatic Unit Testing, pg 37:

"NUnit 2.4 introduced a new style of assertions that are a little less procedural and allow for a more object oriented underlying implementation. ... For instance:

Assert.That(actual, Is.EqualTo(expected));

Converts to:

Assert.That(actual, new EqualConstraint(expected));"

Using constraints also allows you to inherit from Constraint and create your own custom constraint(s) while keeping a consistent syntax.

SnOrfus
A: 

I don't like Assert.That, specifically the fact that its most common scenario (comparing two objects' equality) is measurably worse than the 'classic' Assert.AreEqual() syntax.

On the other hand, I super love the MSpec NUnit extensions. I recommend you check them out (or look at the SpecUnit extensions, or NBehave extensions, or N*Behave*Spec*Unit extensions, I think they're all the same).

Peter Seale