模拟地理编码器 Laravel
Mocking GeocoderLaravel
我正在使用 GeocoderLaravel 通过 Laravel 应用程序中的 Google 地图 API 查找位置。我希望能够模拟外观,以便在测试中它实际上不会查询 Google 映射 API,因此我将其注入控制器,但这样做会破坏控制器。这是控制器的相关部分:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Location;
use Geocoder;
class LocationController extends Controller
{
protected $geocoder;
public function __construct(Geocoder $geocoder)
{
$this->geocoder = $geocoder;
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
// Get location
$location = $request->input('location');
try {
// Look up location
$result = $this->geocoder->geocode($location);
// Return response
return response()->json($result->toArray(), 200);
} catch (\Exception $e) {
$data = [
'message' => $e->getMessage()
];
return response()->json($data, 400);
}
}
}
当我 运行 测试或尝试向此方法发出请求时出现以下错误:
PHP Fatal error: Call to undefined method Toin0u\Geocoder\Facade\Geocoder::geocode()
使用 PsySh 在调用之前插入一个断点,看起来确实定义了 geocode()
方法,但我不确定为什么。谁能解释我哪里出错了?
你不能像那样注入外观。 facade 没有 geocode
方法。
Facades 的特殊之处在于它们只提供对 Laravel IoC 的访问,并且不像正常的 classes 那样表现。它们与依赖注入正交。
如果服务提供商创建了别名,您可以注入真实的 Geocoder\Geocoder
class,但 doesn't appear 以这种方式设置。
我认为您像往常一样坚持使用外观,例如 Geocoder::geocode(...)
。
但是...查看 Laravel 如何在测试期间模拟外观:
https://laravel.com/docs/5.1/testing#mocking-facades
这将允许您测试您的控制器,模拟外观调用,这样它就不会真正命中 Google。
更新:
我已经创建了一个拉取请求来使这个 DI 友好:
https://github.com/geocoder-php/GeocoderLaravel/pull/41
如果该请求被合并,您将能够在您的控制器方法中注入 \Geocoder\Geocoder
,我自己非常喜欢!
我正在使用 GeocoderLaravel 通过 Laravel 应用程序中的 Google 地图 API 查找位置。我希望能够模拟外观,以便在测试中它实际上不会查询 Google 映射 API,因此我将其注入控制器,但这样做会破坏控制器。这是控制器的相关部分:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Location;
use Geocoder;
class LocationController extends Controller
{
protected $geocoder;
public function __construct(Geocoder $geocoder)
{
$this->geocoder = $geocoder;
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
// Get location
$location = $request->input('location');
try {
// Look up location
$result = $this->geocoder->geocode($location);
// Return response
return response()->json($result->toArray(), 200);
} catch (\Exception $e) {
$data = [
'message' => $e->getMessage()
];
return response()->json($data, 400);
}
}
}
当我 运行 测试或尝试向此方法发出请求时出现以下错误:
PHP Fatal error: Call to undefined method Toin0u\Geocoder\Facade\Geocoder::geocode()
使用 PsySh 在调用之前插入一个断点,看起来确实定义了 geocode()
方法,但我不确定为什么。谁能解释我哪里出错了?
你不能像那样注入外观。 facade 没有 geocode
方法。
Facades 的特殊之处在于它们只提供对 Laravel IoC 的访问,并且不像正常的 classes 那样表现。它们与依赖注入正交。
如果服务提供商创建了别名,您可以注入真实的 Geocoder\Geocoder
class,但 doesn't appear 以这种方式设置。
我认为您像往常一样坚持使用外观,例如 Geocoder::geocode(...)
。
但是...查看 Laravel 如何在测试期间模拟外观:
https://laravel.com/docs/5.1/testing#mocking-facades
这将允许您测试您的控制器,模拟外观调用,这样它就不会真正命中 Google。
更新:
我已经创建了一个拉取请求来使这个 DI 友好:
https://github.com/geocoder-php/GeocoderLaravel/pull/41
如果该请求被合并,您将能够在您的控制器方法中注入 \Geocoder\Geocoder
,我自己非常喜欢!