2012-08-02 88 views
1

我正在写一个使用框架遵循MVC模式 - Kohna 3.2的Facebook应用程序。我想测试我的服务器端代码。我决定编写模型的单元测试和功能测试来检查控制器/视图。决定使用PHPUnit。功能测试和外部api

所以我很快遇到了一个问题。如何在请求处理期间为使用外部API的控制器编写函数测试?

我不想使用真正的API调用。它们的执行需要很长时间,并且需要在会话中使用身份验证令牌,并很快失效。另外测试像'在墙上写帖子'这样的东西会产生大量的垃圾邮件。

我真的看不出如何嘲笑这一点。当然,我可以为外部api包装库创建一个模拟对象,但我认为应该通过创建请求并检查其响应来进行功能测试。所以我没有看到一个地方,我可以注入模拟对象..

你会怎么做呢?

+0

所以你想实现假的API来测试你的代码?我对吗? – 2012-08-31 11:37:42

+0

这是正确的。 – Luigi 2012-08-31 14:02:15

回答

0

在回顾我自己的悬而未决的问题,我可以回复自己,使用DIC(依赖注入容器)就是答案。它让具有不同配置的测试enviornment,或测试期间使用单一的PHP程序时,只是进行测试之前设置嘲笑它甚至有可能。

2

1)当测试的东西,它与API包装器一起工作时,应该模拟整个API包装类,并模拟抛出异常作为错误状态和测试,应用程序本身将如何对这些异常做出反应。

它应该停止做一些依赖于API响应的操作,它应该可能会显示一些用户友好的错误。更有甚者,您可以(也可能应该)测试API包装器上的哪些方法被调用了+多少次以及传递了哪些参数。

<?php 

public function testShowUser() { 
    $fb = $this->getMock('Facebook\Api'); 
    $fb->expects($this->once()) // if your library will call getUserInfo() more than once or never, the test will fail 
     ->method('getUserInfo') 
     ->with($this->equalTo('johndoe')) // if the method will be called with different parameter, the test will fail 
     ->will($this->throwException('Facebook\NonExistingUser')); 

    $myApp = new MyApp($fb); 
    $myApp->renderUser('johndoe'); // if this will throw uncaught exception, the test will fail 

    $this->assertEquals(
     array('The user you requested does not exist'), 
     $myApp->getFlashMessages() 
    ); 
} 

2)当测试的API包装本身你可以模拟从API原始响应。

您应该围绕HTTP通信整体的东西分开,一些特定的类(卷曲包装/有自己的单元测试/),并假设服务器返回的一些特定的HTTP代码和响应。

您可以将所有可能的响应类型保存在文件中,以便您可以将它们加载到测试中作为响应。

我建议做这种方式:

<?php 

/** 
* @expectedException Facebook\NonExistingUser 
*/ 
public function testUnavailableApi() { 
    $curl = $this->getMock('CurlWrapper'); 
    $curl->expects($this->once()) 
     ->method('getBody') 
     ->will($this->returnValue(file_get_contents('fb_404_response.json'))); 
    $curl->expects($this->once()) 
     ->method('getStatusCode') 
     ->will($this->returnValue(404)); 

    $api = new Facebook\Api($curl); 
    $api->getUserInfo('johndoe'); 
} 
+0

我知道如何嘲笑事物。我只是想知道,当我创建请求并测试结果时,我怎么能注入这些嘲笑。可以发布此问题的最佳答案,我走到这一步,是使用依赖注入容器,并将其配置为使用模拟的测试,锻造请求之前的时间。 – Luigi 2012-09-11 14:00:26