Using Spy Object in PHPUnit?
Asked Answered
S

4

9

How can I use Spy Object in PHPUnit? You can call object in imitation on, and after you can assert how many times it called. It is Spy.

I know "Mock" in PHPUnit as Stub Object and Mock Object.

Sting answered 7/2, 2011 at 16:24 Comment(1)
What does "You can call object in imitation on" mean? "how many times it called"... you mean "has been called"?Renaterenato
S
11

You can assert how many times a Mock was called with PHPUnit when doing

    $mock = $this->getMock('SomeClass');
    $mock->expects($this->exactly(5))
         ->method('someMethod')
         ->with(
             $this->equalTo('foo'), // arg1
             $this->equalTo('bar'), // arg2
             $this->equalTo('baz')  // arg3
         );

When you then call something in the TestSubject that invokes the Mock, PHPUnit will fail the test when SomeClass someMethod was not called five times with arguments foo,bar,baz. There is a number of additional matchers besides exactly.

In addition, PHPUnit as has built-in support for using Prophecy to create test doubles since version 4.5. Please refer to the documentation for Prophecy for further details on how to create, configure, and use stubs, spies, and mocks using this alternative test double framework.

Selfregulated answered 7/2, 2011 at 16:44 Comment(1)
So I need to spend a week learnig a whole new whopping humongous framework just to be able to use The Full Power Of Code (rather than Extremely Poor Set Of Predefined Crap) to assert about arguments to a stubbed method?Ezequieleziechiele
K
7

There's a spy returned from $this->any(), you can use it something like:

$foo->expects($spy = $this->any())->method('bar');
$foo->bar('baz');

$invocations = $spy->getInvocations();

$this->assertEquals(1, count($invocations));
$args = $invocations[0]->arguments;
$this->assertEquals(1, count($args));
$this->assertEquals('bar', $args[0]);

I put up a blog entry about this at some stage: http://blog.lyte.id.au/2014/03/01/spying-with-phpunit/

I have no idea where (if?) it's documented, I found it searching through PHPUnit code...

Kattie answered 6/5, 2015 at 4:10 Comment(2)
Is it just me or is this no longer the case?Binns
As of 8.4.1, the tests fail as getInvocations() method no longer exists. github.com/sebastianbergmann/phpunit/issues/3888Achromatous
R
0

An update of @lyte's answers that works in 2018:

$foo->expects($spy = $this->any())->method('bar');
$foo->bar('baz');

$invocations = $spy->getInvocations();

$this->assertEquals(1, count($invocations));
$args = $invocations[0]->getParameters();
$this->assertEquals(1, count($args));
$this->assertEquals('bar', $args[0]);
Raama answered 20/11, 2018 at 5:24 Comment(0)
S
0

You can do this :

$mock = $this->getMock('SomeClass');
$mock->expects($spy = $this->any())
    ->method('someMethod')
    ->with(
        $this->equalTo('foo'), // arg1
        $this->equalTo('bar'), // arg2
        $this->equalTo('baz')  // arg3
    );

If you just want to check on call :

self::assertTrue($spy->hasBeenInvoked());

If multiples :

$this->assertEquals(5, count($spy->getInvocations()));
Severus answered 9/1 at 8:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.