dongxiangchan0743 2017-01-18 01:43
浏览 92

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

I'm trying to assert that a method on an object (object under test) is called at least once during the construction of another object. I want to use phpunit's expects() functionality to test that a getDetails() method is called. This function is called during the construction of another customer account object. I must be missing something fundamental about the way phpunit works but I may be approaching the problem with a python mindset. I know I could get this working in python but perhaps it's not possible here? Here is my test code:

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

At this point I would expect the instantiation of the Customer_Account class to call the getDetails method on my mock and the atLeastOnce check to return true.

This code is modified from a real life example. So any typos may have been introduced when re-typing. In the real life code the 'phone_book' is passed into the Customer_Account object's constructor and the getDetails() method is called in that constructor. I have confirmed that the method IS actually being called and I'm getting the return value I expect. However my mock expects() test is failing.

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

The mock is not registering the call to getDetails() even though I'm confident the right code is being called. Is what I'm trying to do just not possible? Do I lose the reference to the mock object once I pass it to another constructor? Is there another way to accomplish this? Any help would be greatly appreciated.

  • 写回答

1条回答 默认 最新

  • dongling3243 2017-08-28 20:18
    关注

    This should work to assert that PhoneBook::details() is invoked with $id when you create an instance of 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
        );
    }
    

    For reference, see:

    评论

报告相同问题?

悬赏问题

  • ¥15 BP神经网络控制倒立摆
  • ¥20 要这个数学建模编程的代码 并且能完整允许出来结果 完整的过程和数据的结果
  • ¥15 html5+css和javascript有人可以帮吗?图片要怎么插入代码里面啊
  • ¥30 Unity接入微信SDK 无法开启摄像头
  • ¥20 有偿 写代码 要用特定的软件anaconda 里的jvpyter 用python3写
  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算