【问题标题】:Testing methods in abstract classes with arguments带有参数的抽象类中的测试方法
【发布时间】:2011-06-17 10:50:22
【问题描述】:

在我的 TDD 项目中,我试图测试抽象类中的方法。

abstract class Database_Mapper_Abstract
{

    public function setTable($sTablename){
        return('foo');

    }
}

这是我编写简单测试的方式:

public function testCanSetTable(){
        $oMock = $this->getMockForAbstractClass('JCMS_Database_Mapper_Abstract');
        $oMock->expects($this->once())
              ->method('setTable')
              ->with($this->equalTo('foo'))
              ->will($this->returnValue('foo'));
        $this->assertEquals('foo',$oMock->setTable());
    }

当我运行此测试时,我收到以下错误:

Sebastian Bergmann 的 PHPUnit 3.5.13。

E

时间:1 秒,内存:6.75Mb

有 1 个错误:

1) Database_Mapper_AbstractTest::testCanSetTable 缺少参数 1 Database_Mapper_Abstract::setTable(),调用 K:\xampp\htdocs\tests\library\Database\Mapper\Abstract.php 在第 15 行并定义

K:\xampp\htdocs\library\Database\Mapper\Abstract.php:4 K:\xampp\htdocs\tests\library\Database\Mapper\Abstract.php:15

失败!测试:1,断言:0, 错误:1。

我的理解是它找不到 setTable 函数的参数。 但我使用with() 方法设置它。我也试过with('foo')。这对我也没有帮助。

有人有想法吗?

【问题讨论】:

  • 我不知道这个测试框架但是如果你把$this->assertEquals('foo',$oMock->setTable());改成$this->assertEquals('foo',$oMock->setTable('foo'));会发生什么
  • 在我看来,你不应该模拟被测类。因为上面的代码没有测试方法 setTable 是否会返回 'foo',它定义方法 setTable 将返回 'foo'。模拟对象用于将它们作为参数传递给被测类,因此您无需创建大型对象图来满足依赖关系。
  • 当我这样做时,我收到此错误:调用 1 次时,方法名称的预期失败等于 。方法预期调用1次,实际调用0次。

标签: php unit-testing phpunit


【解决方案1】:

测试一个抽象类:

为了测试抽象类,您不想使用“创建行为方法”。

就像这样getMockForAbstractClass()

<?php
abstract class JCMS_Database_Mapper_Abstract
{

    public function setTable($sTablename){
        return $sTablename."_test";

    }
}

class myTest extends PHPUnit_Framework_TestCase {

    public function testCanSetTable(){
        $oMock = $this->getMockForAbstractClass('JCMS_Database_Mapper_Abstract');

        $this->assertEquals('foo_test', $oMock->setTable('foo'));
    }

}

您只需使用模拟功能来创建该抽象类的实例并对其进行测试。

这只是写作的捷径

class MyDataMapperAbstractTest extends JCMS_Database_Mapper_Abstract {
    // and filling out the methods
}

实际错误:

发生的情况是您有一个带有一个参数的方法:

public function setTable($sTablename){

但是你用零参数来称呼它:

$oMock->setTable()

所以你会从 PHP 中得到一个错误,如果 PHP 抛出一个警告,PHPUnit 会告诉你一个错误。

转载:

<?php
abstract class JCMS_Database_Mapper_Abstract
{

    public function setTable($sTablename){
        return('foo');

    }
}

class myTest extends PHPUnit_Framework_TestCase {

    public function testCanSetTable(){
        $oMock = $this->getMockForAbstractClass('JCMS_Database_Mapper_Abstract');
        $oMock->expects($this->once())
              ->method('setTable')
              ->with($this->equalTo('foo'))
              ->will($this->returnValue('foo'));
        $this->assertEquals('foo',$oMock->setTable());
    }

}

结果:

 phpunit blub.php
PHPUnit 3.5.13 by Sebastian Bergmann.

E

Time: 0 seconds, Memory: 3.50Mb

There was 1 error:

1) myTest::testCanSetTable
Missing argument 1 for JCMS_Database_Mapper_Abstract::setTable(), called in /home/.../blub.php on line 19 and defined

修复

变化:

$this->assertEquals('foo',$oMock->setTable());

$this->assertEquals('foo',$oMock->setTable('foo'));

那么您不会收到 PHP 警告,它应该可以解决 :)

【讨论】:

  • 我这样做并删除了整个流畅的界面部分,然后它就可以工作了。唯一的问题是我不明白为什么我需要 Fluent 界面的东西。
  • @sanders 更新了我的答案以反映这一点。你不知道,当我告诉你你会的时候,我可能在聊天中误解了你。对不起,如果是这样的话
  • @sanders - 您使用expects() 告诉模拟对象在收到该方法调用时要做什么,或者如果它没有收到它应该使测试失败。在您的情况下,您想测试真正的方法及其返回的内容,因此您不需要期望。相反,只需对返回值使用断言。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-21
  • 1970-01-01
  • 2018-09-23
相关资源
最近更新 更多