建筑商的部分模拟

时间:2018-09-07 13:32:47

标签: php phpunit

我的SUT是使用构建器的服务,我想

  • 验证构建器是否带有正确的参数
  • 控制构建器的返回值

我找不到如何使用phpunit进行存档。因为我想验证参数,但是希望使用构建器的实际方法。

一个简化的示例:

class Builder {
    private $name = "default name";
    private $email = "default@example.com";

    public function withName($name) {
        $this->name = $name;
        return $this;
    }

    public function withEmail($email) {
        $this->email = $email;
        return $this;
    }

    public function build() {
        return new Person($this->name, $this->email);
    }
}

class Person {
    public $name;
    public $email;

    public function __construct($name, $email) {
        $this->name = $name;
        $this->email = $email;
    }
}

class Service {
    private $builder;

    public function __construct(Builder $builder) {
        $this->builder = $builder;
    }

    public function doSomething($email) {
        $person = $this->builder->withEmail($email)->build();
        // Yes, json_encode is the only functionality to test in this simplified example
        return json_encode($person);
    }
}

class Service_Test extends \PHPUnit_Framework_TestCase {

    /** @var Service */
    private $sut;

    /** @var Builder|\PHPUnit_Framework_MockObject_MockObject $builderMock */
    private $builderMock;

    function setUp() {
        parent::setUp();

        $this->builderMock = self::getMockBuilder('Builder')
            ->disableOriginalConstructor()
            ->setMethods(['withEmail', 'build'])
            ->getMock()
        ;

        $this->sut = new Service($this->builderMock);
    }

    public function test_doSomething() {

        $email = "example@example.com";
        $expectedPerson = new Person("P", $email);

        // test the builder is called with the right parameter (simplified in this example email only)
        $this->builderMock->expects(self::once())
            ->method('withEmail')
            ->with($email)
        ;

        // But don't care what the builder is building and specify return
        $this->builderMock->expects(self::once())
            ->method('build')
            ->willReturn($expectedPerson)
        ;

        // This builder is actually called in other class that is omitted in this example
        $actualJson = $this->sut->doSomething($email);

        // Test
        // Yes, verify functionality with same implementation 'json_encode' in this example
        $this->assertEquals(json_encode($expectedPerson), $actualJson);
    }
}

当前代码的问题是,由于我模拟了withEmail以验证参数,因此它不执行real方法,而是返回null。 结果是

Error : Call to a member function build() on null
ABuilder_Test.php:68

我正在寻找将观察与调用实际方法相结合的方法,因为我需要链接构建器操作的实际返回值。

0 个答案:

没有答案
相关问题