php - 功能测试和外部api

标签 php testing phpunit

我正在使用遵循 MVC 模式的框架编写一个 facebook 应用程序 - Kohna 3.2。我想测试我的服务器端代码。我决定为模型编写单元测试,并为检查 Controller / View 编写功能测试。决定对两者都使用 PHPUnit。

于是很快就遇到了问题。如何在请求处理期间为使用外部 api 的 Controller 编写功能测试?

我不想使用真正的 api 调用。它们的执行需要很长时间,并且需要 session 中的身份验证 token ,该 token 很快就会过期。此外,测试诸如“在墙上写帖子”之类的东西会产生大量垃圾邮件。

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

你会怎么做?

最佳答案

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

它可能应该停止执行一些依赖于 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 通信的所有内容分离到某个特定的类(Curl 包装器/具有自己的单元测试/),并假设服务器返回了一些特定的 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' );
}

关于php - 功能测试和外部api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11787051/

相关文章:

php - DBAL 基数违规错误

python - 如何测试放置在子文件夹中的 Django 应用程序?

javascript - 从表中获取属性 - Protractor

php - PHPUnit 代码覆盖率如何忽略我的自动加载器?

php - 在 PHPUnit 中使用 Spy 对象?

php - 显示mysql结果不同输入的总和

php - 我可以通过php执行js文件吗?

cakephp - 对 Auth 组件进行单元测试

laravel - 如何使用 PHPUnit 在 Laravel 上测试更复杂的案例

PHP MVC文件结构