45

What to prefer:

Assert.That(obj.Foo, Is.EqualTo(true))

or

Assert.True(obj.Foo)

For me, both asserts are equivalent, so which one should be prefered?

Tanktalus
  • 21,664
  • 5
  • 41
  • 68
Razer
  • 7,843
  • 16
  • 55
  • 103

4 Answers4

24

In this particular case, there is no difference: you will see the output of roughly the same level of detail (i.e. it tells you that something that was expected to evaluate to true has evaluated to false). Same goes for

Assert.IsTrue(obj.Foo);

and

Assert.That(obj.Foo, Is.True);

Your team should pick one style of assertions, and stick with it throughout all your tests. If your team prefers the Assert.That style, then you should use Assert.That(obj.Foo, Is.True).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    FWIW, our company goes with Assert.That so that your tests can read more like sentences. You would probably read both of these assertions as "Assert that obj.Foo is true", which is literally exactly how the second assertion is written. – EJay Jan 13 '15 at 18:00
15

Assert.That is called the constraint-based model. It's flexible because the method takes a parameter of IConstraint type. This means you can structure your code with a more generic hierarchy or calling structure, passing in any old IConstraint. It means you can build your own custom constraints

That's a design issue. As everyone is saying, no matter what you still need to provide decent error message feedback.

radarbob
  • 4,964
  • 2
  • 23
  • 36
7

So ok, you executed your test suite on CI server and unfortunately, one of them failed. You open the logs and see next message

BusinessLogicTests.LoginTests.UserAutoLoginTests failed: expected true but was false

Now how on earth would you get what happened wrong with this tests, if all the information you see, is that somewhere in AutoLoginTests bool was expected true, but received false? Now you need to go to the source file of your tests cases and see, what assertion failed. You see

Assert.True(obj.Foo)

Amazingly.. it's still hard to tell what's wrong, only if you developed this module 1 hour ago. You still need to go deeper into tests sources and probably production sources or even debug your code, so that you can at last figure out, that you misspelled a variable inside function call or used wrong predicate to filter registered users. Thus you blocked immediate feedback from tests, which is very valuable.

My point is that it's dosn't matter how fluent your assertions are (which are also relevant), but what information you expose in case of failing tests and how fast can you get the underlying reason of failure, even if you worked a long time ago with this functionaluty

Ilya Ivanov
  • 23,148
  • 4
  • 64
  • 90
  • You are completely right. This only was the question regarding the style. There should be a proper output if an assertion fail to easily findout the error. – Razer Apr 18 '13 at 15:53
5

This is a bit nit-picky but IMHO I think that in this case Assert.That is unnecessarily verbose and can therefore be regarded as obfuscation. In other words, Assert.True is a little cleaner, more straightforward and easier to read and therefore comprehend.

To get a little more nit-picky I would suggest using the Assert.IsTrue API instead of Assert.True since, again IMHO, IsTrue "reads" better.

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
  • 1
    I tend to disagree, if you read the statements from left to right you literally get "Assert that object Foo is true" which leans more to the human language. (which is the purpose of Hamcrest). I also suggest to stick with Hamcrest or the default assertions, not mixing them. – Pieter De Bie Nov 14 '18 at 13:11