如何在PHPUnit模拟调用期望中声明参数属性子结构

时间:2017-05-15 05:57:14

标签: php unit-testing phpunit qa

我正在测试发送到模拟事件处理程序的参数。该参数是“事件”子类型的对象,其本身具有嵌套在其中的一些数据。我想测试事件及其子结构与我通过各种模拟注入代码的夹具数据相匹配。

我可以很容易地测试事件的“顶级”:类名和简单属性,如事件名称字符串。我还可以测试一个属性包含相同的对象,我相信它会隐式测试对象的所有子结构。

我遇到的问题是一个更复杂的例子中的一些子结构导致测试失败但是它无关紧要,所以我想挑选子的特定属性 -structure,而不仅仅是身份 - 比较整个对象。

我觉得我在属性断言中缺少一些东西:如何访问“with”所指的参数 - 作为变量。然后我可以把它传递给一些断言方法,比如attributeEqualTo,它要求传入测试中的项目。也许这些只是在我正在使用的流利案例中使用?

  • 我想查看event.data是某个类。
  • 我想查看event.data.thing1 == X
  • 我想查看event.data.thing2 == Y. 等等。

简化代码:

class MyEventData{
    public $thing1;
    public $thing2;
}

class MyEvent{
    public $data;
}

// An event gets fired containing this in the tests
$eventData = new MyEventData(1,2);

$this->eventMock->expects($this->exactly(3))
    ->method('fire')
    ->with(
        $this->logicalAnd(
        // THIS WORKS OK
            $this->isInstanceOf('\MyApp\MyEvents\SomeEvent'), 
            // THIS WORKS OK
            $this->attributeEqualTo ('name', SomeEvent::EVENT_NAME),    
            // THIS WORKS in simplified cases only
            $this->attributeEqualTo ('data', $eventData),

            // HOW DO I GET THE "WITH" PARAMETER CONTEXT "INTO" THE THIRD PARAMETER? 
            $this->assertAttributeInstanceOf('\MyApp\MyEvents\MyEventData', 'data', -classOrObject- ),  

            // Then how can I test with attribute data.thing1 == 1 and data.thing2 = 2

        )
    );

1 个答案:

答案 0 :(得分:0)

我已经使用callback约束让它工作了,但感觉我现在已经离开了路径并失去了PHPUnit的强大功能 - 我似乎无法再次使用断言助手。

e.g。如果累积的测试返回false,则我不会在输出日志中获得超过"期望失败的任何细节......并且被指定的回调接受"。

    $this->callback(function($subject){
        $b = true;
        // I tried using this constraint but can't access (autoload) this class? So is it not supposed to be used directly?
        //$c = new PHPUnit_Framework_Constraint_IsInstanceOf('\MyApp\MyEvents\MyEventData');
        // return $c->matches(subject);

        // this is the right assert, but it doesn't return the result, so I cannot use it in a callback constraint.
        \PHPUnit_Framework_Assert::assertAttributeInstanceOf('\MyApp\MyEvents\MyEventData', 'data', $subject);

        // This works but seems very "Manual"
        $b = $b && get_class($subject->data) == '\MyApp\MyEvents\MyEventData';
        $b = $b && $subject->data->thing1 == 1;
        $b = $b && $subject->data->thing2 == 1;
        return $b;
    })