英文:
How do I mock guzzle request
问题
如何模拟第三方API调用,该调用来自控制器。我在控制器中有以下代码行:
public function store(){
$response = $request->post('http://thirdpaty.app/rmis/api/ebp/requests', [
"headers" => [
'Content-Type' => 'application/json',
],
"json" => [
"data"=>1
]
]);
$data = json_decode($response->getBody()->getContents());
$token = $data->token;
// 将该令牌保存到数据库
}
而在测试中,我正在执行以下操作:
$response = $this->post('/to-store-method');
我如何模拟API请求,以便在测试中不必调用第三方API请求。
目前我正在这样做:
if(app()->get('env') == 'testing'){
$token = 123;
}else{
// 在这里进行API调用
}
是否有更好的替代方法来进行此测试?
英文:
How do I make a mock of third party api call . That is happening from controller . I have this line of code in controller .
public function store(){
$response = $request->post('http://thirdpaty.app/rmis/api/ebp/requests', [
"headers" => [
'Content-Type' => 'application/json',
],
"json" => [
"data"=>1
]
]);
$data = json_decode($response->getBody()->getContents());
$token = $data->token;
// Saving that token to database
}
And from the test I am doing
$response = $this->post('/to-store-method');
How do I mock the api request . So that in testing I don't have to call the third api request .
Right now I am doing
if(app()->get('env') == 'testing'){
$token = 123;
}else{
//Api call here
}
Is there any better alternative of doing this test
答案1
得分: 1
你需要一种方法将一个模拟处理程序注入到你的控制器正在使用的 Guzzle Client 中。传统上,你可以通过将 Guzzle Client 通过构造函数传递或通过一些在代码中引用的服务来实现依赖注入,然后可以在幕后使用 Mockery 进行模拟。
之后,查看 Guzzle 文档以了解如何在 HTTP 客户端中模拟请求的方法:
http://docs.guzzlephp.org/en/stable/testing.html
你可以使用 MockHandler 来执行类似以下代码的操作,通过构建一组虚拟请求和响应:
// 创建一个模拟处理程序并排队两个响应。
$mock = new MockHandler([
new Response(200, ['X-Foo' => 'Bar'], 'Hello, World'),
new Response(202, ['Content-Length' => 0]),
new RequestException('Error Communicating with Server', new Request('GET', 'test'))
]);
$handlerStack = HandlerStack::create($mock);
$client = new Client(['handler' => $handlerStack]);
// 第一个请求被第一个响应拦截。
$response = $client->request('GET', '/');
英文:
You'll need some way of injecting a mock handler into the Guzzle Client your controller is using. Traditionally, you'd either leverage dependency injection by passing the Guzzle Client via the constructor or through some referenced service in that code that you can mock (using Mockery) behind the scenes.
After that, check out the Guzzle documentation for a peak on how to mock requests in the HTTP Client:
http://docs.guzzlephp.org/en/stable/testing.html
You'd use a MockHandler to do something resembling the following code by building a stack of fake requests and responses.
// Create a mock and queue two responses.
$mock = new MockHandler([
new Response(200, ['X-Foo' => 'Bar'], 'Hello, World'),
new Response(202, ['Content-Length' => 0]),
new RequestException('Error Communicating with Server', new Request('GET', 'test'))
]);
$handlerStack = HandlerStack::create($mock);
$client = new Client(['handler' => $handlerStack]);
// The first request is intercepted with the first response.
$response = $client->request('GET', '/');
答案2
得分: -2
实际上,模拟网络库是一个不好的做法。我建议的做法是通过httpService包装网络请求,然后模拟httpService以返回所需的响应。
public function store(){
$response = httpService.postData();
$data = json_decode($response->getBody()->getContents());
$token = $data->token;
// 将该令牌保存到数据库中
}
这样,您可以从httpService.postData函数中获得响应,并且您可以模拟postData而不是网络库。
英文:
Actually, it is a bad practice to mock the network libraries. What I would recommend is to wrap the network request by the httpService and mock the httpService instead to return the required response.
public function store(){
$response = httpService.postData();
$data = json_decode($response->getBody()->getContents());
$token = $data->token;
// Saving that token to database
}
So, the you would get the response as return from the httpService.postData function and you can mock the postData instead of the network library.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论