【问题标题】:How to assert parameter attribute sub-structures in PHPUnit mock call expectations如何在 PHPUnit 模拟调用期望中断言参数属性子结构
【发布时间】:2017-05-15 05:57:13
【问题描述】:

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

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

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

我觉得我在属性断言中遗漏了一些东西:如何访问“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

        )
    );

【问题讨论】:

  • 您的测试目标是哪个对象/类?如果你测试事件处理程序,那么你不应该模拟测试类
  • @AdamW。我没有显示目标 S.U.T。为简单起见。事件模拟是许多接收来自它的调用的注入子系统之一。

标签: php unit-testing phpunit qa


【解决方案1】:

我已经使用callback 约束让它工作了,但感觉就像我现在已经走出了这条路,失去了 PHPUnit 的力量——我似乎不能再在这里使用断言助手了。

例如如果累积的测试返回 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;
    })

【讨论】:

    猜你喜欢
    • 2016-10-04
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 2014-11-14
    相关资源
    最近更新 更多