簡體   English   中英

Laravel 急切加載 phpunit 測試

[英]Laravel eager loading phpunit testing

我正在嘗試執行 GET 請求以通過 id /GET 'film/{id}'等檢索特定電影

film_table

- ID

- 描述

這是響應的一部分,如果我在電影 model 中有多對多關系,如film model 所示

public function languages(): BelongsToMany
{
    return $this->belongsToMany(
        'App\Models\Language',
        'film_languages',
        'film_id',
        'language_code'
    );
}

public function categories(): BelongsToMany
{
    return $this->belongsToMany(
        'App\Models\Category',
        'film_categories',
        'film_id',
        'category_id'
    );
}

有沒有辦法可以將這些表作為響應的一部分包含在內我在 Laravel 文檔中遇到了一種稱為急切加載的內容,但不確定這是否涵蓋了我需要的內容我在下面有一個示例,但如果我在右邊,我會迷路軌道?

FilmController

public function show(string $id): string
{
    /** @var Film  $film*/
    $film = film::findOrFail($id)
        ->with(
            'languages',
            'categories',
            )->get();

    return $film->toJson();

我正在嘗試編寫 PHPUnit 測試,以確保當通過 id 抓取電影時,它會返回iddescription以及從多對多關系中選擇的選項。

這是我開始的測試

FilmControllerTest

public function setUp(): void
{
    parent::setUp();

    $this->film = factory(Film::class)->create();

    $languages = factory(Language::class)->create();

    $categories = factory(Category::class)->create();
}

/**
 * @test
 */
public function it_should_get_film()
{
    $response = $this->json('GET', '/film/' . $this->film->id);

    $film= Film::findOrFail($this->film->id);

    $response->assertJson([
        'id' => $film->id,
        'description' => 'This is my favourite film'
    ]);
}

你能把這些關系包含在工廠中嗎?

FilmFactory

    $factory->define(\App\Models\Film::class, function (Faker $faker) {
    return [
        'id' => $faker->uuid,
        'description' => $faker->paragraph
    ];
});

LanguagesFactory

  $factory->define(\App\Models\Language::class, function (Faker $faker){
    $langCode = $faker->languageCode;
    return [
        'code' => $langCode,
        'name' => $langCode,
    ];
});

CategoriesFactory

    $factory->define(\App\Models\Category::class, function (Faker $faker){

    return [
        'main' => $faker->text,
        'sub' => $faker->text,
    ];
});

我可以得到一些幫助嗎?我已經遇到了一些幫助,例子會很棒:)謝謝!

你走在正確的軌道上。 但是,存在一些語法錯誤。

這就是你如何抓取電影,急切加載所需的關系並將其返回為 JSON:

public function show($id)
{
    $film = Film::with(['languages', 'categories'])->findOrFail($id);

    return $film; // will automatically convert it to JSON
}

這就是你測試它的方式:

public function testShowFilm()
{
    $film = factory(Film::class)->create();

    $language = factory(Language::class)->create();

    $film->languages()->attach($language->id); // associate the film with the language

    $category = factory(Category::class)->create();

    $film->categories()->attach($category->id); // associate the film with the category

    $url = '/films/' . $film->id;

    $this->json('GET', $url)
        ->assertStatus(200)
        ->assertJsonPath(['id' => $film->id])
        ->assertJsonPath(['description' => $film->description])
        ->assertJsonPath(['languages.0.id' => $language->id])
        ->assertJsonPath(['categories.0.id' => $category->id]);
}

請注意,在您的場景中,您應該擁有:

  • 3 model 表:電影、類別、語言;
  • 每個 model 表的工廠;
  • 2 個關系表:film_categories 和film_languages。

然后,您可以使用上例中的attach方法將關系設置為測試的一部分,也可以使用工廠回調:

https://laravel.com/docs/6.x/database-testing#factory-callbacks

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM