2012-10-03 45 views
2

我一直在努力让我们的系统与PHPUnit更加兼容,所以我们可以对类进行更多的单元测试,并设法让它们中的一些模拟对象工作,但是我已经碰到一个我似乎无法解决的问题。在PHPUnit模拟对象中返回不同的结果

我们有一个类(我创建一个模拟版本)用于查询。将查询字符串传递给它的“query()”方法,它将记录查询,运行查询并返回结果。它还使用名为“get_row()”的方法封装了mysql_fetch_assoc,该方法返回的数组值与原始数据非常相似。

问题是,在某些方法中,有多个查询被传递给“query()”方法,因此需要通过多个while循环运行以将数据加载到不同的变量中。我已经创建了一个简化版本:

class object{ 
    public function __construct($query){ 
     $this->query = $query; 
    } 

    public function loadData(){ 

     $data1 = queryDataSource("SELECT * FROM data1"); 
     $data2 = queryDataSource("SELECT * FROM data2"); 

     return Array(
      "data1" => $data1, 
      "data2" => $data2, 
     ); 

    } 

    private function queryDataSource($query){ 
     $this->query->query($query) 

     while($row = $this->query->get_row()){ 
      $result[] = $row; 
     } 

     return $result 
    } 
} 

class testObject extends PHPUnit_Framework_TestCase{ 
    method testLoadData(){ 
     $test_data = Array('name' => 'Bob', 'number' => '98210'); 

     $query = $this->getMock('Query'); 
     $query->expects($this->any())->method('query'); 
     $query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data); 
     $query->expects($this->at(2))->method('get_row')->will($this->returnValue(False); 
     $query->expects($this->at(3))->method('get_row')->will($this->returnValue($test_data); 
     $query->expects($this->at(4))->method('get_row')->will($this->returnValue(False); 
    } 
} 

为了避免第一次while循环$对象 - > queryDataSource()我返回FALSE布尔值,因为这样做mysql_fetch_assoc何时会发生。问题是,当它试图运行第二个查询并通过get_row()获取数据时,模拟对象似乎保持返回FALSE ratehr而不是继续到at(3)点。即使有4个对象也会发生这种情况,只有第一个会将测试数据作为返回值,第二次获取FALSE,其他每次都会得到FALSE。

有谁知道是否有办法解决这个问题?我尝试删除FALSE标志,只是在at()中有奇数值,但是有同样的问题,我试着让它返回(1-2)的数据,但是它只是将所有数据传入首先while循环,而另一个则什么也不做。

感谢您的帮助,您可以给,望

回答

7

,因为它似乎只能是伪代码,但是从我的理解,我不能运行代码不够清晰的问题的是,你试图嘲弄的说明像这样:

Call to query, get_row, get_row, query, get_row, get_row. 

问题,你似乎遇到了是->at()匹配数不按method起来,但每object计数。

所以,你可能希望写的是:

$query->expects($this->any())->method('query'); 
    $query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data); 
    $query->expects($this->at(2))->method('get_row')->will($this->returnValue(False); 
    $query->expects($this->at(4))->method('get_row')->will($this->returnValue($test_data); 
    $query->expects($this->at(5))->method('get_row')->will($this->returnValue(False); 

或者使其豆蔻easer到甚至阅读:

$query->expects($this->at(0))->method('query'); 
    $query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data); 
    $query->expects($this->at(2))->method('get_row')->will($this->returnValue(False); 
    $query->expects($this->at(3))->method('query'); 
    $query->expects($this->at(4))->method('get_row')->will($this->returnValue($test_data); 
    $query->expects($this->at(5))->method('get_row')->will($this->returnValue(False); 

有了您的嘲弄你遇到了问题,第二呼叫“查询”正在计数一个“呼叫”,因此跳过第二个return($test_data);

+0

对于延迟响应抱歉,转移到另一个项目,但应该能够很快回到这个。这看起来可能是问题,会让你知道它是否工作 – SolidSquid

+0

这样做的工作,我曾认为at()的索引是相对于方法而不是对象,所以它跳过了“查询”过程的一部分。另外,抱歉没有发布正在工作的代码。它基于我正在使用的代码,但是写成了一个简化版本,我没有机会在发布之前测试它 – SolidSquid

1

不幸的是,at()非常强烈地将您的测试与实现绑定在一起。

试想一下,如果你重新安排一个测试方法内2个的方法调用,功能是正是相同,但使用at()现在会失败,往往与神秘的消息,如method doesn't exist at index N

在次所有测试要明确地说,“这就是所谓的正是这种方式”,这很好,但如果你只是想断言,那么PHPUnit模拟扩展之一似乎更友好,特别是Mockery和指南here(我相信过时的接触)

还有其他也是。

+0

edorian的解决方案解决了这个问题,但会看看Mockery,看看它是否可以用过的。在这方面有更多的灵活性会很有用。谢谢(你的)信息 – SolidSquid

相关问题