【问题标题】:Expecting partial arrays using PHPUnit mock objects期望使用 PHPUnit 模拟对象的部分数组
【发布时间】:2011-10-11 04:37:41
【问题描述】:

在 PHPUnit 模拟 with() 子句中测试多个数组键的最佳方法是什么?

例如,要测试一个方法调用的第二个参数是否是一个包含'foo' 键的数组:

$this->stubDispatcher->expects($this->once())
        ->method('send')
        ->with('className', $this->arrayHasKey('foo'));

我想做的是类似于$this->arrayHasKey('foo', 'bar'),但实际上并不匹配数组的确切内容。

【问题讨论】:

标签: php phpunit


【解决方案1】:

您可以将断言直接传递给->with(),但它们的名称不同。

有关列表,请查看来源:https://github.com/sebastianbergmann/phpunit/blob/3.5/PHPUnit/Framework/Assert.php#L2097 及以下。不以“assert”开头并返回new PHPUnit_Framework_*的所有内容。

虽然我认为 @David 的回答有效,但我认为这种方法使用 logicalAnd() 更简洁/更易于阅读。

$mock->expects($this->once())->method("myMethod")->with(
    $this->logicalAnd(
        $this->arrayHasKey("foo"),
        $this->arrayHasKey("bar")
    )
);

工作示例

<?php


class MyTest extends PHPUnit_Framework_TestCase {

    public function testWorks() {
        $mock = $this->getMock("stdClass", array("myMethod"));
        $mock->expects($this->once())->method("myMethod")->with(
            $this->logicalAnd(
                $this->arrayHasKey("foo"),
                $this->arrayHasKey("bar")
            )
        );
        $array = array("foo" => 1, "bar" => 2);
        $mock->myMethod($array);
    }

    public function testFails() {
        $mock = $this->getMock("stdClass", array("myMethod"));
        $mock->expects($this->once())->method("myMethod")->with(
            $this->logicalAnd(
                $this->arrayHasKey("foo"),
                $this->arrayHasKey("bar")
            )
        );
        $array = array("foo" => 1);
        $mock->myMethod($array);
    }

}

输出

phpunit assertArrayKey.php 
PHPUnit 3.5.13 by Sebastian Bergmann.

.F

Time: 0 seconds, Memory: 6.50Mb

There was 1 failure:

1) MyTest::testFails
Expectation failed for method name is equal to <string:myMethod> when invoked 1 time(s)
Parameter 0 for invocation stdClass::myMethod(array( <string:foo> => <integer:1> )) does not match expected value.
Failed asserting that an array has the key <string:bar>.

/home/edo/test/assertArrayKey.php:27

【讨论】:

    【解决方案2】:

    您可以使用回调来进行多个断言。

    $this->stubDispatcher->expects($this->once())
         ->method('send')
         ->will($this->returnCallback(function($class, $array) {
                 self::assertEquals('className', $class);
                 self::assertArrayHasKey('foo', $array);
                 self::assertArrayHasKey('bar', $array);
         }));
    

    编辑:如果你想对一些参数进行基本断言,对其他参数进行更复杂的断言,你可以添加with()

    $this->stubDispatcher->expects($this->once())
         ->method('send')
         ->with('className', $this->anything())
         ->will($this->returnCallback(function($class, $array) {
                 self::assertArrayHasKey('foo', $array);
                 self::assertArrayHasKey('bar', $array);
         }));
    

    要非常清楚,您永远不应该将$this-&gt;returnCallback() 传递给with()returnValue()throwException() 相同。这些都是告诉模拟在调用方法时要做什么的指令。 with() 用于告诉 mock 它应该接受哪些参数。

    【讨论】:

    • 谢谢,这很方便。不幸的是,它似乎不适用于 with()。
    • 你确定吗?我以前没有把它们结合起来,但我希望它们能一起工作。但是,以上内容旨在替换您现有的with()
    • 我知道,很奇怪吧?我在 phpunit 3.5.13 上,我收到如下预期错误:Failed asserting that &lt;string:className&gt; is equal to PHPUnit_Framework_MockObject_Stub_ReturnCallback Object (etc)
    • 啊,现在我看到了问题所在。再次阅读我的代码。我正在使用will() 设置ReturnCallback--而不是with()
    • 对,我注意到了。抱歉,如果评论中不清楚。
    猜你喜欢
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多