【问题标题】:creating mock phpunit discrepency in mocked namespace and the original one在模拟命名空间和原始命名空间中创建模拟 phpunit 差异
【发布时间】:2018-02-08 06:30:08
【问题描述】:

我有这样的功能:

class Bar{
    public function a():Foo{
    .
    .
    .
    }
}

现在我正在尝试使用 php 单元测试为类 Bar 创建一个模拟

    $mockedBar = $this->getMockBuilder(Bar::class)
     ->getMock()
     ->method('a')
     ->willReturn(new FakeFoo());

但是当我调用方法 a 时,我收到一个错误,即方法 a 返回类型必须是 Foo 的实例而不是 Mocked_blahblah。

不幸的是,Bar 类没有使用任何接口,而且系统很大,我无法创建接口,因为它在我的代码中进行了巨大的重构; 有没有办法在模拟对象中禁用函数a 的返回类型? 我正在使用 php7.2 和 phpunit 6.0.13。 这是一个真实的场景:

class A
{
    public function b():B
    {
        echo "i am from class A function b";
    }
}
class B
{

}

class FakeB
{
}
class ATest extends TestCase
{
    public function testSayHi(){
        $mockedA = $this->getMockBuilder(A::class)
            ->getMock();
        $mockedA->method('b')->willReturn(new FakeB());
        $mockedA->b();
    }
}

【问题讨论】:

    标签: php unit-testing phpunit php-7.2


    【解决方案1】:

    您不能禁用返回类型。也许您可以尝试使用某种骇人听闻的错误处理程序来实现,但这样做太疯狂了。

    好消息是您没有尝试做任何不寻常的事情,您的测试可以被修复。

    首先,您需要将getMock 的结果分配给一个变量。接下来,您可以定义您的测试替身:

    class MyTest extends TestCase
    {
        public function testIt()
        {
            $mockedBar = $this->getMockBuilder(Bar::class)->getMock();
            $mockedBar
                 ->method('a')
                 ->willReturn(new FakeFoo());
    
            $this->assertInstanceOf(Foo::class, $mockedBar->a());
        }
    }
    

    这仅适用于FakeFoo 的类型为Foo,例如扩展它:

    class FakeFoo extends Foo
    {
        // override any Foo methods you'd like to fake
    }
    

    你不需要自己创建一个Fake,你可以使用PHPUnit创建一个dummy:

    class MyTest extends TestCase
    {
        public function testIt()
        {
            $mockedBar = $this->createMock(Bar::class);
            $mockedBar
                 ->method('a')
                 ->willReturn($this->createMock(Foo::class));
    
            $this->assertInstanceOf(Foo::class, $mockedBar->a());
        }
    }
    

    修正你的第二个例子:

    class A
    {
        public function b():B
        {
            echo "i am from class A function b";
        }
    }
    
    class B
    {
    }
    
    class FakeB extends B
    {
    }
    
    class ATest extends TestCase
    {
        public function testSayHi(){
            $mockedA = $this->getMockBuilder(A::class)->getMock();
            $mockedA->method('b')->willReturn(new FakeB());
            $mockedA->b();
        }
    }
    

    或者,不要使用假的,让 phpunit 处理它:

    class ATest extends TestCase
    {
        public function testSayHi(){
            $mockedA = $this->getMockBuilder(A::class)->getMock();
            $dummyB = $this->createMock(B::class);
    
            $mockedA->method('b')->willReturn($dummyB);
            $mockedA->b();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-01-08
      • 2020-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-29
      • 1970-01-01
      • 2021-07-18
      相关资源
      最近更新 更多