在依赖的PHPUnit测试之间传递的对象会发生什么?

Ian*_*ips 6 php phpunit mocking depends

这不是一个问题,而是试图在PHPUnit上浪费我的其他时间.

我的问题是我的模拟对象,当在依赖测试中使用时,没有返回预期值.看来,PHPUnit的不保留相关测试之间的同一个对象,即使语法使它看起来像它.

有谁知道为什么PHPUnit这样做?这是一个错误吗?PHPUnit中的这类内容使得使用起来非常令人沮丧.

<?php 
class PhpUnitTest
extends PHPUnit_Framework_TestCase
{
private $mock;

public function setUp()
{
    $this->mock = $this->getMock('stdClass', array('getFoo'));

    $this->mock->expects( $this->any() )
        ->method('getFoo')
        ->will( $this->returnValue( 'foo' ) );
}

public function testMockReturnValueTwice()
{
    $this->assertEquals('foo', $this->mock->getFoo());
    $this->assertEquals('foo', $this->mock->getFoo());

    return $this->mock;
}

/**
 * @depends testMockReturnValueTwice
 */
public function testMockReturnValueInDependentTest($mock)
{
    /* I would expect this next line to work, but it doesn't! */
    //$this->assertEquals('foo', $mock->getFoo());

    /* Instead, the $mock parameter is not the same object as
     * generated by the previous test! */
    $this->assertNull( $mock->getFoo() );
}

}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ess 5

PHPUnit中的Mock对象附加到为其创建的测试实例,这个定义意味着单个测试方法.这样做的原因是PHPUnit允许您指定在测试期间必须满足的模拟的期望.为此,一旦方法成功终止,它就会断言这些期望.如果模拟在测试中存在,那么期望就不会起作用.

问题是这不支持存根对象:仅包含为响应方法和输入而采取的固定操作的模拟.存根不会验证他们的方法被称为完全模拟可以.也许PHPUnit可以从创建存根的能力中受益,因为存根setUpBeforeClass()不依赖于测试实例.

您的另一个选择是使用外部模拟对象库,如MockeryPhake.

编辑:再次查看您的示例代码后,我想知道为什么您对这种行为感到惊讶.正如Shaunak写的那样,setUp()在每个测试方法执行之前调用一个新实例.因此,每个实例都会收到一个新的模拟stdClass.如果只需要一种测试方法来获得期望,请将其添加到测试方法本身中.您仍然setUp()可以使用所有测试方法应该具有的任何行为来创建模拟对象.

  • @Ian - 依赖方法中的注释掉调用失败告诉我`__phpunit_cleanup()`必须删除`getFoo()`期望. (2认同)