如何使用Laravel Localization进行单元测试? [英] How to do unit testing with Laravel Localization?
问题描述
我正在使用mcamara/laravel-localization
软件包,但无法弄清楚如何使其与我的单元测试一起使用.以下两个都失败并显示红色:
I'm using mcamara/laravel-localization
package and I can't figure out how to make it work with my unit tests. Both of the following fail with red:
// 1. This one results in "Redirecting to http://myapp.dev/en"
$this->get('/')->assertSee('My App Homepage');
// 2. This one results in 404
$this->get('/en')->assertSee('My App Homepage');
在浏览器中,http://myapp.dev
返回302,并将其重定向到http://myapp.dev/en
,这很合理.但是,http://myapp.dev/en
返回200.因此,这两种情况在前端都可以100%很好地工作,但不能用于单元测试.
In the browser, http://myapp.dev
returns 302 with a redirect to http://myapp.dev/en
, fair enough. However, http://myapp.dev/en
returns 200. So both cases work 100% fine on the front-end, but not with unit tests.
我做但是有一些自定义项,它再次在浏览器中像魅力一样工作.
I do have some customization however, which once again, works like charm in the browser.
// in web.php
Route::group([
'prefix' => app('PREFIX'), // instead of LaravelLocalization::setLocale()
'middleware' => ['localeSessionRedirect', 'localizationRedirect']],
function() {
Route::get('/', function() {
return view('home');
});
}
]);
// in AppServiceProvider.php
public function boot()
{
// This, unlike LaravelLocalization::setLocale(), will determine the
// language based on URL, rather than cookie, session or other
$prefix = request()->segment(1); // expects 'en' or 'fr'
$this->app->singleton('PREFIX', function($app) use ($prefix) {
return in_array($prefix, ['en', 'fr']) ? $prefix : null;
});
}
希望这段代码对您有意义.谢谢!
Hopefully this code makes sense to you. Thanks!
我通过 GitHub问题#435 中的软件包解决了此问题.
I addressed this problem with the package in a GitHub issue #435.
据我所知,只要您在phpunit XML文件的基本URL中指定语言环境,就可以安全地测试本地化的路由:
Insofar as I could figure it out, it seems that you can safely test your localized routes as long as you specify the locale in the base URL in your phpunit XML file:
<env name="APP_URL" value="http://myapp.dev/en"/>
但是,这将适用于本地化的GET端点(以语言环境前缀开头,例如'en'),但不适用于非本地化的POST,PUT等(不具有任何前缀).因此,除非您使用Dusk,否则您无法真正同时测试这两种端点(我不这样做,因为它是一个过大的工具,而且速度较慢,几乎与手动执行相同).
However, this would work for your localized GET endpoints (which start with a locale prefix, e.g. 'en'), but not for non-localized POST, PUT, etc. (which don't have any prefix). Hence, you can't really test both kinds of endpoints at the same time, unless you use Dusk (which I don't, as it's an overkill and much slower, almost the same as doing it manually).
推荐答案
我发现,如果您在测试过程中转储请求URL,则无论您访问哪个端点,它都是始终 http://myapp.dev
.因此,LaravelLocalization::setLocale()
和我的自定义app('PREFIX')
都返回null
,这意味着在测试过程中不会定位任何一条路由.这两种方法都会给您带来麻烦,因为如果您尝试访问不带区域设置前缀的路由,则会收到302,但是如果您指定了区域设置,则框架将找不到该路由的定义.
I found that if you dump the request URL during testing, it is always http://myapp.dev
no matter what endpoint you're accessing. So both LaravelLocalization::setLocale()
and my custom app('PREFIX')
return null
, meaning that not a single route is ever localized during testing. You are screwed either way because if you try to access a route without a locale prefix, you get a 302, but if you do specify the locale, the framework can't find a definition for that route.
一篇文章帮助我找到了一个临时解决方案:您需要在laravellocalization.php
中将hideDefaultLocaleInURL
更改为true
.这样,与您的默认语言环境匹配的路由将没有任何前缀,因此您可以像对它们进行本地化一样对其进行测试.
One article helped me discover a temporary solution: you need to hideDefaultLocaleInURL
to true
in laravellocalization.php
. This way, the routes matching your default locale won't have any prefix, so you can test them as if they were non-localized.
但是,问题仍然存在,因为在 本地化后应该如何测试您的应用程序? (例如,当您有需要测试的特定于语言的路由时).这就提出了一个问题,即该程序包本身是否与单元测试兼容?
However, the problem still persists, because how are you supposed to test your application when it is localized? (For ex., when you have language-specific routes that need to be tested). This poses the question whether this package is even compatible with unit testing per se...
这篇关于如何使用Laravel Localization进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!