简体   繁体   English

在模拟命名空间和原始命名空间中创建模拟 phpunit 差异

[英]creating mock phpunit discrepency in mocked namespace and the original one

I have function like this:我有这样的功能:

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

now I am trying to create a mock for the class Bar with php unit test现在我正在尝试使用 php 单元测试为 Bar 类创建一个模拟

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

but when I am calling method a I am getting an error that method a return type must be instance of Foo not Mocked_blahblah.但是当我调用方法a我收到一个错误,该方法a返回类型必须是 Foo 的实例,而不是 Mocked_blahblah。

unfortunately class Bar don't use any interface and the system is very big and I can't create an interface cause it make huge refactor in my codes;不幸的是,Bar 类不使用任何接口,而且系统非常大,我无法创建接口,因为它在我的代码中进行了大量重构; is there any way to disable return type of function a in mocked object?有没有办法在模拟对象中禁用函数a返回类型? I am useing php7.2 and phpunit 6.0.13.我正在使用 php7.2 和 phpunit 6.0.13。 Here is a real scenario:这是一个真实的场景:

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();
    }
}

You can't disable return types.您不能禁用返回类型。 Perhaps you could try to do it with some kind of a hackish error handler, but it's a crazy thing to do.也许您可以尝试使用某种骇人听闻的错误处理程序来做到这一点,但这是一件疯狂的事情。

Good news is that you're not trying to do anything unusual and your tests can be fixed.好消息是您不会尝试做任何不寻常的事情,并且您的测试可以得到修复。

Firstly, you need to assign the result of getMock to a variable.首先,您需要将getMock的结果分配给一个变量。 Next, you can define your test double:接下来,您可以定义您的测试替身:

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());
    }
}

This will only work if FakeFoo is of type of Foo , for example extends it:这仅在FakeFooFoo类型时才有效,例如扩展它:

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

You don't need to create a Fake yourself, you can use PHPUnit to create a dummy:你不需要自己创建一个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());
    }
}

To fix your second example:要修复您的第二个示例:

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();
    }
}

Or, instead of using a fake let phpunit handle it:或者,而不是使用假的让 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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM