PHPUnit将mock对象作为参数传递给另一个对象的构造函数并使用expected()方法

时间:2017-01-18 01:43:39

标签: php unit-testing testing mocking phpunit

我试图断言在构造另一个对象期间,对象(被测对象)上的方法至少被调用一次。我想使用phpunit的expected()函数来测试是否调用了getDetails()方法。在构建另一个客户帐户对象期间调用此函数。我必须遗漏一些关于phpunit工作方式的基本信息但我可能正在接近python心态的问题。我知道我可以在python中使用它,但也许这不可能吗? 这是我的测试代码:

public function testPhoneBookCode()
{
    $account = 'testaccount';

    $phone_book_mock = $this->getMockBuilder('\corp\data\PhoneBook')
        ->setConstructorArgs(array(null))
        ->setMethods(null)
        ->getMock();

    $expected = array(
        'id' => 1234,
        'title' => 'Mr',
        'first_name' => 'George',
        'last_name' => 'Smith',
        'phone' => '111-111-1111'
    );

    $phone_book_mock->expects($this->atLeastOnce())
        ->method('getDetails')
        ->with($this->equalTo(1234))
        ->will($this->returnValue($expected));

    try {
        $c = new Customer_Account(
            $account,
            true,
            'acme_corp',
            1234,
            null,
            null,
            $phone_book_mock
        );

    } catch ( \Exception $e ) {
        $this->fail("An unexpected exception has been raised [$account].". $e);
    }
}

此时我希望Customer_Account类的实例化在我的mock上调用getDetails方法,并且atLeastOnce检查返回true。

此代码是从现实生活中修改的。因此,重新键入时可能会引入任何拼写错误。在现实代码中,'phone_book'被传递到Customer_Account对象的构造函数中,并且在该构造函数中调用getDetails()方法。我已经确认实际上正在调用方法IS,并且我得到了我期望的返回值。但是我的模拟期望()测试失败。

  

方法名称的期望失败等于至少调用一次。   预期调用至少一次,但从未发生过。

即使我确信正在调用正确的代码,模拟也没有注册对getDetails()的调用。我想做的就是不可能吗?将模型对象传递给另一个构造函数后,是否会丢失对模拟对象的引用?还有另一种方法来实现这一目标吗?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

当您创建PhoneBook::details()的实例时,这应该可以断言用$id调用Customer_Account

public function testPhoneBookCode()
{
    $id = 1234;

    $details = [
        'id' => $id,
        'title' => 'Mr',
        'first_name' => 'George',
        'last_name' => 'Smith',
        'phone' => '111-111-1111'
    ];

    $phoneBook = $this->createMock('corp\data\PhoneBook');

    $phoneBook
        ->expects($this->atLeastOnce())
        ->method('getDetails')
        ->with($this->identicalTo($id))
        ->willReturn($details);

    new Customer_Account(
        'testaccount',
        true,
        'acme_corp',
        $id,
        null,
        null,
        $phoneBook
    );
}

供参考,见: