David Harkness | 10 Jun 2010 00:48

Enhancing assertion failure messages with context via SelfDescribing

Hi guys,

One of the things I've added to my controller test case base class is a slew of assertions that validate a value in the view. They work exactly like the assertAttributeXXX() family of assertions in that they grab a value from the view and perform an assertion on it. When the view doesn't have the value the assertion failure is descriptive

    Failed asserting the view has a value for "foo".

But just as with assertAttributeXXX() if the XXX assertion fails you lose the context of which attribute was being accessed.

    Failed asserting that <string:foo> equals <string:bar>.

What I'd like to see is this

    Failed asserting that view attribute "foo" with value <string:foo> equals <string:bar>.

One way to do this would be to allow the $actual values passed to other assertions to check if the object implements an interface that extends SelfDescribing to add a getValue() method. All of the code in readAttribute() would go into getValue() and toString() would build the string

    attribute "$name" of [class|object] with value [value]

Since this object is passed as $actual to assertXXX(), it can call getValue() to perform the assertion and if it fails, AssertionFailedError (or whatever class builds the failure message) can call toString() to get the description.

Is this something that belongs more to Hamcrest? Speaking of Hamcrest, is that still the plan for PHPUnit 4.0?

Thanks,
David

David Harkness | 10 Jun 2010 00:59

Re: Enhancing assertion failure messages with context via SelfDescribing

I've just reread your post about Hamcrest and noticed that you can pass an "identifier" string as the first parameter to assertThat(). Given that using Hamcrest removes the need for all the extra assertXXX() methods, I could easily create assertThatViewValue($name, ...) to call assertThat() with a pre-built identifier of "View value $name".

This is obviously a lot easier and is totally sufficient. Please disregard my previous post. Now to convince my team to use 3.5 beta now instead of waiting two years. :)

David


Gmane