代码之家  ›  专栏  ›  技术社区  ›  berty

在phpunit中,如何期望一个精确的mock作为方法调用的参数,而不是同一类的任何mock?

  •  0
  • berty  · 技术社区  · 7 年前

    在下面的示例中(使用php 7.3ans phpunit 7.5.1),我有两个同一类的模拟。我希望两个模拟中的一个作为方法调用中的参数。但是,如果我用另一个模拟调用该方法,则期望似乎得到了满足。

    <?php declare(strict_types=1);
    
    use PHPUnit\Framework\MockObject\MockObject;
    use PHPUnit\Framework\TestCase;
    
    class ExampleTest extends TestCase
    {
        public function testExample()
        {
            $mock1 = $this->getMockBuilder(stdClass::class)->getMock();
            $mock2 = $this->getMockBuilder(stdClass::class)->getMock();
            /** @var MockObject|ArrayObject $mock3 */
            $mock3 = $this->getMockBuilder(ArrayObject::class)->setMethods(['append'])->getMock();
    
            $this->assertEquals($mock1, $mock2); // OK
            $this->assertNotSame($mock1, $mock2); // OK
    
            $mock3->expects($this->once())->method('append')->with($mock1); // OK
    
            // However I pass $mock2 instead of $mock1 !
            $mock3->append($mock2);
    
            // I would need something like :
            // $mock3->expects($this->once())->method('append')->withSameAs($mock1); // Not OK
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Richie Hughes    7 年前

    我想你想打电话给 $this->identicalTo 功能在 with 功能。这将验证是否传递了正确的对象。如果更新代码以传入 $mock1 它应该失败,因为对象不同

    use PHPUnit\Framework\MockObject\MockObject;
    use PHPUnit\Framework\TestCase;
    
        class ExampleTest extends TestCase
        {
            public function testExample()
            {
                $mock1 = $this->getMockBuilder(stdClass::class)->getMock();
                $mock2 = $this->getMockBuilder(stdClass::class)->getMock();
                /** @var MockObject|ArrayObject $mock3 */
                $mock3 = $this->getMockBuilder(ArrayObject::class)
                    ->setMethods(['append'])->getMock();
    
                $mock3->expects($this->once())->method('append')->with($this->identicalTo($mock2)); // OK
                $mock3->append($mock2);
    
            }
        }
    

    其他例子:

    use PHPUnit\Framework\MockObject\MockObject;
    use PHPUnit\Framework\TestCase;
    
    class ExampleTest extends TestCase
    {
        public function testExample()
        {
            $mock1 = $this->getMockBuilder(stdClass::class)->getMock();
            $mock2 = $this->getMockBuilder(stdClass::class)->getMock();
            /** @var MockObject|ArrayObject $mock3 */
            $mock3 = $this->getMockBuilder(ArrayObject::class)
                ->setMethods(['append'])->getMock();  
    
            $class = new ExampleClass($mock3);
            $mock3->expects($this->once())->method('append')->with($this->identicalTo($mock2)); // OK
            $class->appendObject($mock2);
    
        }
    }
    
    class ExampleClass
    {
        private $array;
    
        public function __construct(ArrayObject $array)
        {
            $this->array = $array;
        }
    
        public function appendObject($stdClass)
        {
            $this->array->append($stdClass);
        }
    }