Laravel使用正则表达式Assert重定向

toiithl6  于 2023-08-08  发布在  其他
关注(0)|答案(3)|浏览(83)

我最近在用laravel尝试TDD,我想Assert重定向是否将用户带到具有整数参数的url。我想知道我是否可以使用正则表达式来捕获所有正整数。
我用laravel 5.8框架运行这个应用程序,我知道url参数是1,因为我每次测试都会刷新数据库,所以将重定向url设置为/projects/1可以工作,但这种硬编码感觉很奇怪。
我已经附上了一个代码块,我尝试使用正则表达式,但这不起作用

/** @test */
    public function a_user_can_create_projects()
    {
        // $this->withoutExceptionHandling();

        //If i am logged in
        $this->signIn(); // A helper fxn in the model

        //If i hit the create url, i get a page there
        $this->get('/projects/create')->assertStatus(200);

        // Assumming the form is ready, if i get the form data
        $attributes = [
            'title' => $this->faker->sentence,
            'description' => $this->faker->paragraph
        ];

        //If we submit the form data, check that we get redirected to the projects path
        //$this->post('/projects', $attributes)->assertRedirect('/projects/1');// Currently working
        $this->post('/projects', $attributes)->assertRedirect('/^projects/\d+');

        // check that the database has the data we just submitted
        $this->assertDatabaseHas('projects', $attributes);

        // Check that we the title of the project gets rendered on the projects page 
        $this->get('/projects')->assertSee($attributes['title']);

    }

字符串
我期望测试将assertRedirect('/^projects/\d+');中的参数视为regex,然后传递任何url,如/projects/1,到目前为止,它以数字结尾,但它将其视为原始字符串,并期望/^projects/\d+的url
我会很感激你的帮助。

pexxcrt2

pexxcrt21#

在看了Jeffery Way的教程后,他谈到了如何处理这个问题。他是这样解决问题的

//If we submit the form data, 
$response = $this->post('/projects', $attributes);

//Get the project we just created
$project = \App\Project::where($attributes)->first();

// Check that we get redirected to the project's path
$response->assertRedirect('/projects/'.$project->id);

字符串

vtwuwzda

vtwuwzda2#

这是不可能的。您需要使用正则表达式测试响应中的Location头。
这是一个问题,因为您不能使用当前路由名称.这就是为什么我做了两个函数来增加测试的可读性。你将像这样使用这个函数:

// This will redirect to some route with an numeric ID in the URL.
$response = $this->post(route('groups.create'), [...]);

$this->assertResponseRedirectTo(
    $response,
    $this->prepareRoute('group.detail', '[0-9]+'),
);

字符串
这就是实现。

/**
 * Assert whether the response is redirecting to a given URI that match the pattern.
 */
public function assertResponseRedirectTo(Illuminate\Testing\TestResponse\TestResponse $response, string $url): void
{
    $lastOne = $this->oldURL ?: $url;
    $this->oldURL = null;

    $newLocation = $response->headers->get('Location');

    $this->assertEquals(
        1,
        preg_match($url, $newLocation),
        sprintf('Should redirect to %s, but got: %s', $lastOne, $newLocation),
    );
}

/**
 * Build the pattern that match the given URL.
 * 
 * @param mixed $params
 */
public function prepareRoute(string $name, $params): string
{
    if (! is_array($params)) {
        $params = [$params];
    }

    $prefix = 'lovephp';
    $rep = sprintf('%s$&%s', $prefix, $prefix);
    $valuesToReplace = [];

    foreach ($params as $index => $param) {
        $valuesToReplace[$index] = str_replace('$&', $index . '', $rep);
    }

    $url = preg_quote(route($name, $valuesToReplace), '/');
    $this->oldURL = route($name, $params);

    foreach ($params as $index => $param) {
        $url = str_replace(
            sprintf('%s%s%s', $prefix, $index, $prefix),
            $param,
            $url,
        );
    }

    return sprintf('/%s/', $url);
}

2ul0zpep

2ul0zpep3#

您可以从响应头中获取Location值,并以这种方式进行匹配

$this->assertMatchesRegularExpression(
  '#/^projects/\d+#', 
  $response->headers->get('Location')
);

字符串

相关问题