PHP 单元测试模拟成员变量依赖

PHP Unit Test Mocking a member variable dependency

你好,假设我想测试 Class A 中的函数 运行,并且我正在使用 Mockery 模拟外部依赖项:

class A {
    protected myB;

    public function __construct(B $param) {
      $this->myB = $param;
    }

    protected function doStuff() {
      return "done";
    }

    public function run() {
      $this->doStuff();

      $this->myB->doOtherStuff();

      return "finished";
    }
}

class B {
    public function doOtherStuff() {
      return "done";
    }
}

所以我这样写了测试:

public function testRun() {
    $mockB = Mockery::mock('overload:B');
    $mockB->shouldReceive('doOtherStuff')
        ->andReturn("not done");

    $mockA = Mockery::mock(A::class)->makePartial()->shouldAllowMockingProtectedMethods();
    $mockA->shouldReceive('doStuff')->andReturns("done");
    
    $mockA->run();
}

这会抛出一个异常: 错误:在 null

上调用成员函数 doStuff()

我尝试了模拟在 运行 函数中调用的内部依赖项 B 的不同变体,但我总是以异常结束。

我做错了什么?

不要嘲笑你正在测试的东西。将模拟的 B 注入 A.

    public function testRun()
    {
        // Arrange
        $mockB = Mockery::mock(B::class);
        $a = new A($mockB);

        // Assert
        $mockB->shouldReceive('doOtherStuff')
            ->once()
            ->andReturn("not done");

        // Act
        $a->run();
    }

如果你想猴子补丁 A,你仍然可以在 (more details: constructor arguments in mockery):

中传递模拟的 B
    public function testRun()
    {
        // Arrange
        $mockB = Mockery::mock(B::class);
        $a     = Mockery::mock(A::class, [$mockB])
            ->makePartial()
            ->shouldAllowMockingProtectedMethods();
        $a->shouldReceive('doStuff')
            ->andReturns('mocked done');

        // Assert
        $mockB->shouldReceive('doOtherStuff')
            ->once()
            ->andReturn('not done');

        // Act
        $a->run();
    }