我在Laravel中有一个使用Guzzle的控制器端点
我在Guzzle Client周围编写了一个包装器,然后创建了一个ServiceProvider。
$this->app->singleton('guzzleclient', function ($app) {
return new Client([
// Base URI is used with relative requests
'base_uri' => $app['config']['api']['url'],
// You can set any number of default request options.
'timeout' => 3.0,
]);
});
$this->app->singleton('client', function ($app) {
return new ClientAdapter($app['guzzleclient']);
});
DI的这种方法使我能够使用Guzzle对来自Guzzle底座的以下模拟:UnitTest我的Adapter类: http://docs.guzzlephp.org/en/latest/testing.html
$stream = \GuzzleHttp\Psr7\stream_for('string data');
// Create a mock and queue two responses.
$mock = new MockHandler([
new Response(200, [], $stream),
new Response(200, ['Content-Length' => 0]),
new RequestException("Error Communicating with Server", new Request('GET', '/'))
]);
$handler = HandlerStack::create($mock);
$client = new Client(['handler' => $handler]);
$adapter = new ClientAdapter('','',$client);
// The first request is intercepted with the first response.
$this->assertEquals(
$adapter->getInfo([])->getStatusCode(),
200
);
这是有效的,现在是我的问题 - (以及关于如何使用IoC和DI的概念的问题)
我想开始进行集成测试,我会调用我的控制器并用我的MockData交换Guzzle调用并测试控制器组件。
$stream = \GuzzleHttp\Psr7\stream_for('string data');
// ... init MockHandler...
// ....
public function testExample()
{
$this->get('/');
$this->assertEquals(
$this->response->getContent(), 'string data'
);
}
然而,由于控制器使用app('client'); IoC从IoC初始化$client
(在产品中它是我想要的)但是在测试中,我如何确保我想要如上所示模拟的那个是被调用的那个而不是来自IoC的那个?这就是我难倒的地方。
答案 0 :(得分:0)
在Laravel中相当简单,只需将'client'绑定到新创建的模拟对象:
$this->app->singleton('client', function ($app) use ($client) {
return new ClientAdapter('', '', $client);
});
您还可以执行app() - > bind()将一个实现替换为另一个实现。请参阅official documentation
中的详情