2

とを使用してモデル間の関係をテストしようとしています。関係を方向でテストできますが、方向でテストするのに問題があります。ArdentFactoryMuffbelongs_tohas_many

私がテストしているモデルは、住宅用不動産賃貸アプリケーションであり、対応する賃貸履歴です。非常に単純化された db スキーマ:

+--------------+
| applications |
+--------------+
| id           |
| name         |
| birthday     |
| income       |
+--------------+

+----------------+
| history        |
+----------------+
| id             |
| application_id |
| address        |
| rent           |
+----------------+

これは私の履歴モデルです:

class History extends Ardent
{
    protected $table = 'history';

    public static $factory = array(
        'application_id' => 'factory|Application',
        'address' => 'string',
        'rent' => 'string',
    );

    public function application()
    {
        return $this->belongsTo('Application');
    }
}

これは、履歴オブジェクトがレンタル アプリケーションに属していることを確認するための私のテストです。

class HistoryTest extends TestCase
{
    public function testRelationWithApplication()
    {
        // create a test rental history object
        $history = FactoryMuff::create('History');

        // make sure the foreign key matches the primary key
        $this->assertEquals($history->application_id, $history->application->id);
    }

}

これはうまくいきます。ただし、関係を逆方向にテストする方法がわかりません。プロジェクト要件では、レンタル アプリケーションには少なくとも 1 つのレンタル履歴オブジェクトが関連付けられている必要がありますこれは私のアプリケーションモデルです:

class Application extends Ardent
{
    public static $rules = array(
        'name' => 'string',
        'birthday' => 'call|makeDate',
        'income' => 'string',
    );

    public function history()
    {
        return $this->hasMany('History');
    }

    public static function makeDate()
    {
        $faker = \Faker\Factory::create();
        return $faker->date;
    }
}

これは私がhas_many関係をテストしようとしている方法です:

class ApplicationTest extends TestCase
{
    public function testRelationWithHistory()
    {
        // create a test rental application object
        $application = FactoryMuff::create('Application');

        // make sure the foreign key matches the primary key
        $this->assertEquals($application->id, $application->history->application_id);
    }
}

これはErrorException: Undefined property: Illuminate\Database\Eloquent\Collection::$application_id 、単体テストを実行したときに発生します。それは私には理にかなっています。オブジェクトに対応するオブジェクトをFactoryMuff少なくとも 1 つ作成するように指示したことはありません。また、オブジェクトには少なくとも 1 つのオブジェクトが必要であるという要件を強制するコードも作成していません。HistoryApplicationApplicationHistory

質問

  1. 「オブジェクトには少なくとも 1 つのapplicationオブジェクトが必要です」というルールを適用するにはどうすればよいhistoryですか?
  2. has_many関係の方向性をテストするにはどうすればよいですか?
4

1 に答える 1

1

はい、両端からそれぞれ各モデルへのアクセスが必要になる可能性があるため、常に双方向でリレーションシップをテストする必要があります。

強制に関しては、私が知っているプログラムによる方法はありません。has() メソッドを使用して、モデルを呼び出すときにインラインで実行する必要があります。

$application = Application::find($id)->has('history', '>=', 1)->get();

hasMany() 関係がコレクションを返すようになったため、実際には Collection のインスタンスの application_id プロパティにアクセスしようとしています。

これをテストするには 2 つの選択肢があります。1 つ目は、以下のようにループして assertEquals を実行することです。

foreach($application->history as $history) {
    $this->assertEquals($application->id, $history->application_id);
}

ここで、テストを行っており、作成されたモデルのインスタンスはテスト目的であるため、次のようなことを行う価値があるかもしれません:

$history = $application->history->first();
$this->assertEquals($application->id, $history->application_id);

繰り返しますが、問題は hasMany() リレーションシップが、子リレーションシップが 1 つしかない場合でも、常に Illuminate\Database\Eloquent\Collection のインスタンスを返すことですが、上記の 2 つのメソッドで十分です。それが役立つことを願っています。

PS:私の例には、変数がnullでないことなどを確認するための検証が含まれていません。テストに追加する価値があるかもしれません。

- アップデート -

残念ながら、私は FactoryMuff に詳しくありませんが、私が信じているように動作する場合は、テストで次のことができるはずです。

$application = FactoryMuff::create('Application');
$history = FactoryMuff::create('History');
$application->history()->save($history);

実際のアプリケーション コードを参照している場合は、モデル イベントにフックして、その場で新しい History オブジェクトを追加するだけです。

于 2013-12-16T23:26:01.893 に答える