PHP 单元测试 : How to test low level functions of an external api

标签 php testing phpunit

你好 各位, 我为 XmlRPC-Api 编写了一个低级实现,但在测试通信时遇到了麻烦。

这是我的代码。

abstract class BaseClient
{
    protected function call($method, array $params = array())
    {
        $request = xmlrpc_encode_request($method, $parameters);

        $file = file_get_contents($this->getDSN(), false, $context);
        $response = xmlrpc_decode($file);

        if ($response && xmlrpc_is_fault(array($response))) {
            trigger_error("xmlrpc: {$response[faultString]} ({$response[faultCode]})");
        }

        return $response;
    }
}


Client extends BaseClient
{
    public function testCall($msg)
    {
        return $this->call('testMethid', array($msg));
    }
}

这是我的测试。

ClientTest extends PHPUnit_FrameWork_TestCase
{
    public function testTestCall()
    {
        $c = new Client();
        $resp = $c->testCall('Hello World');

        $this->assertEquals('Hello World', $resp);
    }
}

此测试每次都会崩溃,因为无法在测试环境中访问 api。 我看不到模拟和注入(inject) call 函数的解决方案。我能做些什么?也许我的对象结构不好并且无法测试 我该如何改进这个结构(如果发生这种情况)?

干杯。

最佳答案

由于您正在尝试测试外部 API,因此我首先将您的 file_get_contents() 调用包装在另一个类中,并将其注入(inject)到您的 BaseClient 中。以最简单的形式,它可能看起来像这样:

class RemoteFileRetriever
{
    public function retrieveFileContents($url)
    {
        // Do some work to create $context
        ...

        // Now grab the file contents
        $contents = file_get_contents($url, false, $context);

        return $contents;
    }
}

abstract class BaseClient
{
    private $fileRetriever;

    public function __construct(RemoteFileRetriever $fileRetriever)
    {
        $this->fileRetriever = $fileRetriever;
    }

    protected function call($method, array $params = array())
    {
        ...

        $file = $this->fileRetriever->retrieveFileContents($this->getDSN());

        ...
    }
}

现在在您的测试中,您可以使用模拟对象作为文件检索器注入(inject)。例如:

class ClientTest extends PHPUnit_FrameWork_TestCase
{
    public function testTestCall()
    {
        $mockRetriever = new MockRemoteFileRetriever();
        $c = new Client($mockRetriever);
        $resp = $c->testCall('Hello World');

        $this->assertEquals('Hello World', $resp);
    }
}

PHPUnit 实际上有一些内置的模拟助手。请参阅PHPUnit's Mock Objects .

关于PHP 单元测试 : How to test low level functions of an external api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18254410/

相关文章:

php - 优化 MySQL 和 PHP 中的多个查询

PHP/MySQL/jQuery(管理员用户)聊天

php - MariaDB错误: the used command is not allowed with this MariaDB

c# - SendKeys 到 Windows 文件对话框

php - 分别提交发票数量记录和数量发票

testing - 测试期间 Dexterity 类型的 ComponentLookupError

android - .isDisplayed - Selenium + Appium

PHPUnit 和 DBUnit - 入门

php - Laravel 测试与存储假

testing - 如何拥有多个不同配置的测试环境?