我正在为我的控制器编写一些测试,但其中一个测试不起作用。它应该进行搜索并将结果返回到页面。但它实际上是重定向到主页。这是我的代码:
use DatabaseMigrations;
protected $user;
public function setUp()
{
parent::setUp();
$this->seed();
$this->user = factory(User::class)->create(['role_id' => 3]);
}
/** @test */
public function test_manage_search_user()
{
$response = $this->followingRedirects()->actingAs($this->user)->get('/manage/users/search', [
'choices' => 'username',
'search' => $this->user->username,
]);
$response->assertViewIs('manage.users');
$response->assertSuccessful();
$response->assertSee($this->user->email);
}
要使其正常工作,您应该获得的 URL 如下所示:
http://localhost/manage/users/search?choices=username&search=Test
我又检查了一下,好像在get请求的参数中没有给出。我该如何解决这个问题?
我在尝试测试
GET
请求时遇到了同样的问题,实际上您无法使用$this->get('uri', [header])
传递参数,但您可以使用$this->call
,如果您签入MakesHttpRequests.php,您可以看到this->get()
实际上是使用call方法。
通过向 get 方法添加数组,您正在更改请求标头,这就是您无法获取参数的原因。
public function get($uri, array $headers = [])
{
$server = $this->transformHeadersToServerVars($headers);
return $this->call('GET', $uri, [], [], [], $server);
}
public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
{
$kernel = $this->app->make(HttpKernel::class);
$files = array_merge($files, $this->extractFilesFromDataArray($parameters));
$symfonyRequest = SymfonyRequest::create(
$this->prepareUrlForRequest($uri), $method, $parameters,
$cookies, $files, array_replace($this->serverVariables, $server), $content
);
$response = $kernel->handle(
$request = Request::createFromBase($symfonyRequest)
);
if ($this->followRedirects) {
$response = $this->followRedirects($response);
}
$kernel->terminate($request, $response);
return $this->createTestResponse($response);
}
因此,如果您想测试
GET
请求,您必须这样做:
$request = $this->call('GET', '/myController', ["test"=>"test"]);
在您的控制器中,您应该能够获取这些参数,如下所示:
public function myController(Request $request)
{
$requestContent = $request->all();
$parameter = $requestContent['test'];
}
我使用的是 Laravel 5.X(更准确地说是 5.6),您可以使用以下方式传递自定义参数:
$response = $this->json('GET', '/url/endpoint',['params'=>'value']);
您可以使用路由助手来构建带有查询字符串的 url。在你的情况下我会做这样的事情。假设路由名称是manage.users.search
$route = route('manage.users.search', [
'choices'=> 'username',
'search' => $this->user->username,
]);
$response = $this->followingRedirects()
->actingAs($this->user)
->get($route);
为了通过 GET 请求发送参数。
如果您使用
route()
方法,那么您可以将数据作为第二个参数传递。
$response = $this->get(route('route_name', ['key' => value]));
如果直接使用URL,可以这样使用
$response = $this->get('url?' . Arr::query(['key' => value]));
用
$response
做任何你想做的事。
您可以使用请求助手合并 http 获取参数,如下所示:
/** @var \Illuminate\Http\Request $request */
$request = request();
$request->merge([
'choices' => 'username',
'search' => 'Test'
]);
这对我来说很有效,只需将参数作为网址的一部分传递,如下所示:
$response = $this->get('api/endpoint?parameter1='.$this->dynamicParam);
添加辅助功能:
if (!function_exists('extend_url_with_query_data')) {
function extend_url_with_query_data(string $url, array $queryData): string
{
if ($queryData == []) {
return $url;
}
$glue = mb_strpos($url, '?') === false ? '?' : '&';
$queryString = http_build_query($queryData);
return "{$url}{$glue}{$queryString}";
}
}
用途:
$queryData = [
'works' => true,
];
$this->get(
extend_url_with_query_data('/api/v1/example', $queryData)
);
聚会迟到了,但我一直在用这个
public function getJsonWithParams($uri, $headers = [], $params = []): TestResponse
{
return $this->getJson($uri . '?' . http_build_query($params), $headers);
}
对于发现来说并不令人惊奇,但它确实有效。
在这里,因为我忘记了我创建了它,所以来寻找想法。
我会这样做:
$this->actingAs($this->user);
$response = $this->get('/manage/users/search', [
'choices' => 'username',
'search' => $this->user->username,
]);
$response->assertViewIs('manage.users');
$response->assertSuccessful();
$response->assertSee($this->user->email);