PHP单元测试:如何测试外部api的低级功能 [英] PHP Unit Testing: How to test low level functions of an external 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屋!