【问题标题】:phpunit: mock object not fooling phpphpunit:模拟对象不欺骗php
【发布时间】:2014-03-27 20:16:23
【问题描述】:

我正在检查zend tutorials,我正在使用 phpunit 测试一个带有模拟对象的类。当我将一个从 Zend\Db\TableGateway 创建的模拟传递给我的类时,谁的构造函数需要一个 Zend\Db\TableGateway,我收到一个类型错误:

"...Argument 1 passed to Album\Model\AlbumTable::__construct() must be an instance of Zend\Db\TableGateway\TableGateway, instance of Mock_TableGateway_65b55cb0 given..."

这应该发生吗? phpunit 模拟对象是否应该能够“欺骗”该类?

这是真正的类:

class AlbumTable {
    protected $tableGateway;

    public function __construct(TableGateway $tableGateway) {
        $this->tableGateway = $tableGateway;
    }

    public function fetchAll() {
        $resultSet = $this->tableGateway->select();
        return $resultSet;
    }

    public function getAlbum($id){
        $id = (int) $id;
        $rowset = $this->tableGateway->select(array('id' => $id));
        $row = $rowset->current();
        if(!$row) {
            throw new \Exception("Couldn't find row: $id");
        }
        return $row;
    }

    public function saveAlbum(Album $album) {
        $data = array(
            'artist' => $album->artist,
            'title' => $album->title,
        );

        $id = (int)$album->id;
        if ($id == 0) {
            $this->tableGateway->insert($data);
        } else {
            if ($this->getAlbum($id)) {
                $this->tableGateway->update($data, array('id' => $id));
            } else {
                throw new \Exception('Form id does not exist');
            }
        }
    }

    public function deleteAlbum($id) {
        $this->tableGateway->delete(array('id' => $id));
    }

}

和测试:

class AlbumTableTest extends PHPUnit_Framework_TestCase {
    public function testFetchAllReturnsAllAlbums() {
        $resultSet = new ResultSet();
        $mockTableGateway = $this->getMock('Zend\Db\TableGateway',
            array('select'), array(), '', false);

        $mockTableGateway->expects($this->once())
            ->method('select')
            ->with()
            ->will($this->returnValue($resultSet));

        $albumTable = new AlbumTable($mockTableGateway);
        $this->assertSame($resultSet, $albumTable->fechAll());
    }
}

和错误:

Time: 102 ms, Memory: 5.00Mb

There was 1 error:

1) AlbumTest\Model\AlbumTableTest::testFetchAllReturnsAllAlbums
Argument 1 passed to Album\Model\AlbumTable::__construct() must be an instance of Zend\Db\TableGateway\TableGateway, instance of Mock_TableGateway_65b55cb0 given, called in C:\Users\MEEE\Google Drive\code\iis\www\CommunicationApp\module\Album\test\AlbumTest\Model\AlbumTableTest.php on line 20 and defined

C:\Users\MEEE\Google Drive\code\iis\www\CommunicationApp\module\Album\src\Album\Model\AlbumTable.php:9
C:\Users\MEEE\Google Drive\code\iis\www\CommunicationApp\module\Album\test\AlbumTest\Model\AlbumTableTest.php:20

FAILURES!
Tests: 4, Assertions: 9, Errors: 1.

【问题讨论】:

  • 创建模拟后,做一个 var_dump 看 instanceof 是否返回 true... var_dump($mockTableGateway instanceof Zend\Db\TableGateway);

标签: oop unit-testing zend-framework2 phpunit


【解决方案1】:

您没有嘲笑正确的课程。您正在创建 Zend\Db\TableGateway 的模拟,您需要实际模拟 Zend\Db\TableGateway\TableGateway

将您的测试代码更改为:

    $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway',
        array('select'), array(), '', false);

您的模拟未能通过类型提示,因为您没有模拟正确的类。

Mock 对象将扩展您正在模拟的类,因此它们将是被模拟的类的实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 2013-06-29
    • 2011-07-27
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多