【问题标题】:Laravel testing url to resource in public directoryLaravel 测试公共目录中资源的 URL
【发布时间】:2022-01-10 18:39:05
【问题描述】:

我正在使用 Laravel Dusk 测试页面上的所有链接,这些链接是 PDF 文件,它们通过 laravel mix 从资源/文档复制到公共/文档。
问题是尝试使用 get(uri) 方法访问文档的 URL 时会出现 404,这是我 Dusk 的简化版本:

protected function refreshApplicationWithLocale($locale)
{
    self::tearDown();
    putenv(LaravelLocalization::ENV_ROUTE_KEY . '=' . $locale);
    self::setUp();
}

protected function setUp(): void
{
    parent::setUp();
    if(!File::copyDirectory( resource_path('docs'), public_path() . '/docs'))
        throw new \Exception("couldn't copy the folder :(");
    // Storage::assertExists(public_path() . '/docs/clothing/existing_file.pdf'); // this assertion fails, what's weird is the path in the exception message does actually exist
    $this->artisan('storage:link');
}

protected function tearDown(): void
{
    parent::tearDown();
    foreach (static::$browsers as $browser) {
        $browser->driver->manage()->deleteAllCookies();
    }
}

public function testClothing()
{
    $this->refreshApplicationWithLocale('fr');
    $this->get('/test')->assertStatus(200); // passes
    $this->get('/fr/vetements')->assertStatus(200); // passes
    //usually I'd get the page urls dynamically with Dusk, but for simplicity sake I'm just testing with this link that I know it exists and can curl it from withing Homestead
    $this->get('/docs/clothing/Hoodies.pdf')->assertStatus(200); //failes (404)
}

我错过了什么?
谢谢。
P.S.:我正在使用 laravel 8 和 Homestead

编辑:
在@steven7mwesigwa 回答之后,这是我的最终代码:

protected function refreshApplicationWithLocale($locale)
{
    self::tearDown();
    putenv(LaravelLocalization::ENV_ROUTE_KEY . '=' . $locale);
    self::setUp();
}

protected function setUp(): void
{
    parent::setUp();
    if(!File::copyDirectory( resource_path('docs'), public_path() . '/docs'))
        throw new \Exception("couldn't copy the documents folder :(");
}

protected function tearDown(): void
{
    parent::tearDown();
    foreach (static::$browsers as $browser) {
        $browser->driver->manage()->deleteAllCookies();
    }
}

public function testClothing()
{
    $this->refreshApplicationWithLocale('fr');
    $elements = [];
    $this->browse(function (Browser $browser) use(&$elements){
        $elements = $browser->visit('myroute')
            ->elements('.tmp_products_list a', 'href');
    });
    $this->assertGreaterThan(1, count($elements));
    foreach($elements as $element) {
        $response = Http::get($element->getAttribute('href'));
        self::assertEquals($response->status(), 200);
    }
}

【问题讨论】:

    标签: laravel testing homestead laravel-dusk laravel-testing


    【解决方案1】:

    问题 1:

    // Storage::assertExists(public_path() . '/docs/clothing/existing_file.pdf');

    // this assertion fails, what's weird is the path in the exception message does actually exist

    Storage 外观使用配置中活动的存储 文件 (config/filesystems.php)。请注意,这默认为local。 为每个存储选项设置根路径。在本地的情况下, 它指向我脑海中的storage/app。 - @bobbybouwmann

    另外,通过storage 路径搜索的正确方法是首先指定filesystem "disk"。即,对于驻留在 storage/app/public/demo.js 中的文件:

    Storage::disk("public")->assertExists("demo.js");

    除此之外,由于您所需的测试文件位于公共文件夹中,因此可以使用以下方法进行测试:

    $this->assertFileExists(public_path() . '/docs/clothing/existing_file.pdf');

    问题 2:

    //usually I'd get the page urls dynamically with Dusk, but for simplicity sake I'm just testing with this link that I know it exists and can curl it from withing Homestead

    $this->get('/docs/clothing/Hoodies.pdf')->assertStatus(200); //failes (404)

    上面的 sn-p 代码不起作用,因为$this->get(...) 本质上是在应用程序的路由文件中搜索一个明确定义的路由,该路由文件对应于未找到的该路径。

    您必须使用浏览器测试框架(即 Laravel Dusk)来测试 Web 服务器上的静态文件。

    更多内容可以在这里找到:How to test for static files located in the web folder in symfony with phpunit?

    不过,由于您已经在使用 Laravel Dusk,这可以通过以下方式实现:

            $this->browse(function (Browser $browser) {
                $browser->visit('/docs/clothing/Hoodies.pdf')
                    ->assertDontSee("404")
                    ->assertDontSee("NOT FOUND");
            });
    
    

    如果 URL 有效且 PDF 文件存在且已加载,则不会加载 HTML 视图。因此测试应该通过。

    如果 URL 无效,将加载 Laravel 默认的 404.blade.php 视图。此视图包括以下文本字符串:“404”和“未找到”。因此在这种情况下测试会失败。

    如果您已经有自定义 404错误页面,请随意更改assertDontSee(....)方法参数中传递的文本字符串。

    【讨论】:

    • 哦,非常感谢您提供的信息丰富的回答。如果我们更改 404 页面(例如,如果我们用图像而不是文本替换它)或者如果请求引发另一种异常(例如 500 或其他东西),是否有某种方法可以覆盖这种情况?谢谢!
    • 我最终使用了 Laravel HTTP 客户端,我已经用代码更新了我的问题,如果您有任何 cmets/建议,请告诉我。谢谢!
    猜你喜欢
    • 2011-07-11
    • 2012-09-17
    • 1970-01-01
    • 2015-11-24
    • 2013-03-28
    • 2018-02-13
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多