2016-09-27 63 views
0

我想要做的事:创建一个不执行__constructor()的Mock对象,但是它有编码的所有方法(没有被模拟为返回null)。使用PHPUnit中的模拟对象测试实际的类方法

The docs说:

“默认情况下,原始类的所有方法都替换为 虚拟实现,只是返回null(不调用 原始方法)使用will($this->returnValue())方法,为 。实例中,您可以配置这些虚拟实现以在调用时返回 值。“

这不是我想要的。我不想强制一种方法返回已知的值。我想测试方法本身,因此需要一个正常运行的类的实例化,但是使用禁用的构造函数。

我该怎么做?

+0

这真的引出了一个问题:为什么你不想执行构造函数?通常情况下,这只是您必须执行的功能,必须以书面形式执行,以便正确设置对象以测试课程。 Mock对象用于所述类的依赖关系,以便能够在不涉及第三方系统或其他业务代码的情况下对其进行适当测试。 – ChristianF

回答

0

我为类本身编写测试用例,返回给定参数所需的数据,而不使用Mocks。 Mocks是用于这个类的外部引用,它需要知道函数Bar()返回Foo,所以等待该响应的类正确处理结果。

鉴于这种很干脆的PHP类:

<?php 
class CATEGORY_SCOPE 
{ 
    public $CategoryName; 
    public $CategoryNo; 

    function __construct($CategoryNo = NULL, $CategoryName = NULL) 
    { 
     $this->CategoryName = $CategoryName; 
     $this->CategoryNo = $CategoryNo; 
    } 

    protected function SetCategoryName($Name) 
    { 
     $this->CategoryName = Name; 
    } 
} 
?> 

我将对其进行测试:

<?php 
require_once(substr(__FILE__, 0, -5)); // strip '.test' extension 
class TEST_CATEGORY_SCOPE extends PHPUnit_Framework_TestCase 
{ 
    protected function setUp() 
    { 
    } 

    public function testObjectCreation() 
    { 
     $CategoryInfo = new CATEGORY_SCOPE(); 
     $this->assertInstanceOf('CATEGORY_SCOPE', $CategoryInfo); 
    } 

    public function testConstructFieldOrder() 
    { 
     $CategoryInfo = new CATEGORY_SCOPE(1500, 'Category Name'); 
     $this->assertEquals(1500, $CategoryInfo->CategoryNo); 
     $this->assertEquals('Category Name', $CategoryInfo->CategoryName); 
    } 

    public function testConstructDefaults() 
    { 
     $CategoryInfo = new CATEGORY_SCOPE(); 
     $this->assertNull($CategoryInfo->CategoryNo); 
     $this->assertNull($CategoryInfo->CategoryName); 
    } 

    public function testSetCategoryName() 
    { 
     $CategoryInfo = new CATEGORY_SCOPE(); 
     $CategoryInfo->SetCategoryName('New Name'); 
     $this->assertEquals('New Name', $CategoryInfo->CategoryName); 
    } 
} 
?> 

这会对测试的类本身的工作,而且我可以设置一定的值。显然这是一个简单的例子。现在,当有些东西使用这个类时,我仍然可以通过目录测试字段设置,但是这里已经介绍了。

对于你的问题,假设我有类FOO(),它接受CATEGORY_SCOPE作为构造函数中的一个参数。您可以模拟CATEGORY_SCOPE类,并设置内部Bar()函数以返回某些数据,而不管CATEGORY_SCOPE类的处理如何。

<?php 
class FOO 
{ 
    public $ReturnValue 
    function __construct($CategoryScope) 
    { 
     $this->ReturnValue = $CategoryScope->Bar(); 
    } 
} 
?> 

通过嘲讽CATEGORY_SCOPE类,这样的酒吧()函数总是返回5(有些价值是有道理的,以你的代码),然后你可以测试Foo类按预期工作。

<?php 
require_once(substr(__FILE__, 0, -5)); // strip '.test' extension 
class TEST_FOO extends PHPUnit_Framework_TestCase 
{ 
    protected function setUp() 
    { 
    } 

    public function testObjectCreation() 
    { 
     $FooInfo = new FOO(); 
     $this->assertInstanceOf('FOO', $FooInfo); 
    } 

    public function testFoo() 
    { 
     // Set Up the Mock so Bar() returns 5 using your mock library 

     ... <- Actual code for the mock goes here 

     $FooInfo = new FOO($CategoryMock); 
     $this->assertEquals(5, $FooInfo->Bar()); 
    } 
} 
?>