Bram
Bram

Reputation: 95

PHPUnit overwrite actual method with stub

I just started playing around with PHPUnit and I was wondering if it is possible to overwrite/replace a method with a stub. I have some experience with Sinon, and with Sinon this is possible (http://sinonjs.org/docs/#stubs)

I want to something like this:

<?php

class Foo {

  public $bar;

  function __construct() {
    $this->bar = new Bar();
  }

  public function getBarString() {
    return $this->bar->getString();
  }

}

class Bar {

  public function getString() {
    return 'Some string';
  }

}



class FooTest extends PHPUnit_Framework_TestCase {

  public function testStringThing() {
    $foo = new Foo();

    $mock = $this->getMockBuilder( 'Bar' )
      ->setMethods(array( 'getString' ))
      ->getMock();

    $mock->method('getString')
      ->willReturn('Some other string');

    $this->assertEquals( 'Some other string', $foo->getBarString() );
  }

}

?>

Upvotes: 2

Views: 2322

Answers (1)

l-x
l-x

Reputation: 1571

This will not work, you will not be able to mock the Bar instance inside the Foo instance. Bar is instantiated inside Foo's constructor.

A better approach would be to inject Foo's dependency to Bar, i. e.:

<?php

class Foo {

  public $bar;

  function __construct(Bar $bar) {
    $this->bar = $bar;
  }

  public function getBarString() {
    return $this->bar->getString();
  }
}

class Bar {

  public function getString() {
    return 'Some string';
  }

}

class FooTest extends PHPUnit_Framework_TestCase {

  public function testStringThing() {

    $mock = $this->getMockBuilder( 'Bar' )
      ->setMethods(array( 'getString' ))
      ->getMock();

    $mock->method('getString')
      ->willReturn('Some other string');

    $foo = new Foo($mock); // Inject the mocked Bar instance to Foo

    $this->assertEquals( 'Some other string', $foo->getBarString() );
  }
}

See http://code.tutsplus.com/tutorials/dependency-injection-in-php--net-28146 for a little tutorial an DI.

Upvotes: 2

Related Questions