使用PHPUnit模拟对象期望部分数组

Kri*_* K. 9 php phpunit

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

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

$this->stubDispatcher->expects($this->once())
        ->method('send')
        ->with('className', $this->arrayHasKey('foo'));
Run Code Online (Sandbox Code Playgroud)

我想要做的是像$this->arrayHasKey('foo', 'bar')实际上没有匹配数组的确切内容.

edo*_*ian 10

您可以直接传递断言,->with()但它们的命名方式不同.

有关列表,请查看源代码:https://github.com/sebastianbergmann/phpunit/blob/3.5/PHPUnit/Framework/Assert.php#L2097以及后续内容.所有不以"断言"开头并返回的东西new PHPUnit_Framework_*.

虽然我认为@David的答案有效,但我认为这种方法使用起来logicalAnd()更清晰/更容易阅读.

$mock->expects($this->once())->method("myMethod")->with(
    $this->logicalAnd(
        $this->arrayHasKey("foo"),
        $this->arrayHasKey("bar")
    )
);
Run Code Online (Sandbox Code Playgroud)

工作实例

<?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);
    }

}
Run Code Online (Sandbox Code Playgroud)

产量

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
Run Code Online (Sandbox Code Playgroud)


Dav*_*ess 5

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

$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);
     }));
Run Code Online (Sandbox Code Playgroud)

编辑:如果你想对某些参数做出基本断言,对其他参数做更复杂的断言,你可以添加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);
     }));
Run Code Online (Sandbox Code Playgroud)

要超清晰,你永远不应该传递$this->returnCallback()with().同样的returnValue()throwException().这些都是告诉mock在调用方法时要做什么的所有指令.with()是告诉模拟它应该接受什么参数.