Phpunit: Custom error messages while checking method invocation

Created on 20 Nov 2014  路  5Comments  路  Source: sebastianbergmann/phpunit

In PhpUnit we are able to create a custom message when a test fails:

$this->assertEquals($check, $result, 
             'Class::method returned the wrong result with argument XXX');

However, it seems that we can't set a custom error message while testing for method invocation:

$mock->expects($this->any())->method('foobar')->with($this->equals('dummy'));

When the above assertion is not true, I get the standard message.
Is it possible to add custom error message for invocations, too?

Most helpful comment

@DragonBe, For me, this was not about testing the functionality, but rather debugging my test that was broken. It didn't give me a line number of the failed expectation just that 'the method named create was never called' it was a mild inconvenience that took me 2 minutes to track down. But could it be simplified, it may have helped.

All 5 comments

@tampe125 your mock should not report a custom error message if that's not the purpose of the object you're mocking.

Create your mock, than assert your functionality. In your case it would be

$mock = $this->getMock('Foo', array ('foobar'));
$mock->expects($this->any())->method('foobar')->with($this->equals('dummy'));

$this->assertTrue($mock->foobar('dummy', 'Expected Foo:foobar() returned not true');

You're assertions should provide the message, not your mocks.

Is it possible to add custom error message for invocations, too?

This is not currently possible. It's an interesting idea, but not currently on the roadmap as far as I know.

@DragonBe , I just ran across this in my testing today (2 years later) and I wasn't needing it to validate my tests ran correctly, but rather that I had several objects being mocked with the method name of "create" and It was mildly frustrating hunting down which object was actually failing.

Perhaps in this case, the error message could include a classname as well?

@zombiesplat, Yes it's a common problem if you have multiple object stubs where you mocked out the same method. It's easy to say add the ClassName::method() to your comment, but if you already have a legacy application, it can be troublesome.

A good rule-of-thumbs is to have your test focus on a single responsibility. I rather write 5 individual tests to test similar logic over 5 different classes as to write it all in a single test. I can then use the test method name to indicate which functionality I'm testing from which class. Yes, a little bit more work upfront but a lot easier to track later on.

@DragonBe, For me, this was not about testing the functionality, but rather debugging my test that was broken. It didn't give me a line number of the failed expectation just that 'the method named create was never called' it was a mild inconvenience that took me 2 minutes to track down. But could it be simplified, it may have helped.

Was this page helpful?
0 / 5 - 0 ratings