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

标签 php unit-testing testing mocking phpunit

我试图断言一个对象(被测对象)的方法在另一个对象的构造过程中至少被调用一次。我想使用 phpunit 的 expects() 功能来测试是否调用了 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 类的实例化在我的模拟上调用 getDetails 方法并且 atLeastOnce 检查返回 true。

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

Expectation failed for method name is equal to when invoked at least once. Expected invocation at least once but it never occured.

模拟没有注册对 getDetails() 的调用,即使我确信调用了正确的代码。我想做的事情是不可能的吗?一旦将模拟对象传递给另一个构造函数,我是否会丢失对模拟对象的引用?还有另一种方法可以做到这一点吗?任何帮助将不胜感激。

最佳答案

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

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

引用:

关于PHPUnit 将模拟对象作为参数传递给另一个对象的构造函数并使用 expects() 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41710082/

相关文章:

php - 在一个 php 文件中设置数组并在另一个 php 文件中访问问题

php - 一个 View 的两个 Controller ,CodeIgniter?

php - {} 在 MySQL 查询中做什么?

c++ - gmock - 测试模拟方法参数

django - 使用 South/Selenium 进行 Django 测试的装置

unit-testing - 当我删除 fmt.Println() 时,golang 中的猴子修补失败

android - 在 VM 中 Dockerize android 模拟器

c# - 如何使用 C# 编写自动化系统测试?

php - 如何选择一列具有两个不同属性的行?

angularjs - 测试具有许多依赖项的 Angular Controller