PHP单元测试:如何测试外部api的低级功能 [英] PHP Unit Testing: How to test low level functions of an external api

查看:107
本文介绍了PHP单元测试:如何测试外部api的低级功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好 乡亲们 我为XmlRPC-Api写了一个低级实现,但是我无法测试通信.

Hello folks, I wrote a low level implementation for a XmlRPC-Api and I've trouble to test the communication.

这是我的代码.

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. 我看不到模拟并注入call函数的解决方案.我能做些什么?也许我的对象结构不好并且无法测试 以及如何改善这种结构(如果发生这种情况)?

This test will crash every time, because its not possible to access the api inside a testing environment. I can't see a solution to mock and inject the call function. What can I do? Maybe my object structure is bad and not able to test and how can I improve this structure (if this happen)?

干杯.

推荐答案

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

Since you're trying to test an external API, I would begin by wrapping your file_get_contents() call in another class and injecting that into your BaseClient. In the simplest form, it might look something like this:

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());

        ...
    }
}

现在在测试中,您可以使用模拟对象作为文件检索器进行注入.例如:

Now in your test, you can use a mock object to inject as the file retriever. E.g.:

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的模拟对象.

PHPUnit atually has some built-in helpers for mocking. See PHPUnit's Mock Objects.

这篇关于PHP单元测试:如何测试外部api的低级功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆