如何测试一个类似参数模拟名称类的方法

时间:2017-09-28 20:59:07

标签: php unit-testing testing mocking phpunit

我有一个像这样的方法

public function prePersist(LifecycleEventArgs $event)
{
    $em = $event->getEntityManager();
    $entity = $event->getObject();
    $metadata = $em->getClassMetadata(get_class($entity));

}

我已经测试了getEntityManagergetObject方法,但现在是时候测试getClassMetadata方法和每个参数了,在这种情况下,它只有一个!

get_class($entity)

上面的行返回名称类(随机):

Mock_ObjectManager_126b0394
Mock_ObjectManager_cc9f593f
Mock_ObjectManager_8e119a34

它永远不会返回实名类...我希望在调用getClassMetadata时检查第一个参数集。

    $test = $this;
    $this->em->expects($this->at(0))
             ->method('getClassMetadata')
             ->with(
                $this->callback(function($arg) use ($test) {
                 $test->assertThat($arg, 
                  $this->logicalAnd(
                   $this->equalTo('ObjectManager')
                  )
                 );//assertThat
                return true;
              }) // callback                                    
             )
             ->willReturn($this->objectManager);

如何测试?

1 个答案:

答案 0 :(得分:1)

你的问题是PHPUnit扩展了类来模拟它们并为它们分配随机化名称。我看到两个(在我看来,hackish)选项:

首先,更糟糕的是,因为您需要修改生产代码。您可以使用get_parent_class()代替get_class(),这样您就可以获得ObjectManager而不是模拟名称。这显然不太理想,如果ObjectManager是一个子类,它根本不会工作(编辑 get_parent_class()获得直接父级,而不是最高级父级,所以它仍然可以在这种情况下工作 - edit2 这不会起作用。如果ObjectManager不是子类,它将返回false并且相反,请尝试从测试中的名称实例化类,并断言它是ObjectManager的孩子。

另一个选项,不是那么糟糕但仍然不完美,是检查assertContains()参数中是否包含ObjectManager

$this->callback(function($arg) use ($test) {
    $test->assertContains("ObjectManager", $arg);//assertThat
    return true;
}) // callback