web-dev-qa-db-ja.com

データが経時的に変化する可能性があるデータを返すリポジトリメソッドの単体テストを作成する方法

データベースから5つの数値を読み取るコードがいくつかあります。

class Repository extends DatabaseRepository
{
    function getCoefficients(string $model)
    {
        return $this->getDatabaseLink()->query("
            select a, b, c, d, e from coefficients 
            where model = ? and active = 1
        ", $model)->getSingleResult();
    }
}

上記のメソッドを呼び出すと、次のようなものが返されます。

array (
  'a' => '0.0001',
  'b' => '0.001',
  'c' => '0.01',
  'd' => '0.1',
  'e' => '1.0'
)

返される数値は、特定のレコードが常にactiveであることに基づいて、時間とともに変化する可能性があります。

このための単体テストを作成するにはどうすればよいですか?書いてもいいですか?何をテストしますか?ライブデータベースの処理を回避するために、データベースをモックアップできますが、実際には何をテストするのでしょうか。

今持っているもの

とりあえず先に進んでテストを作成しました。これは、ライブデータベースを使用して返される正確な数をテストしますが、データベース内の関連データが変更されるか、データベースの実装が変更されると(テストではライブデータベースを呼び出して設定します)。

特定の質問

  • リポジトリレベルで何をテストする必要がありますか?
  • ライブデータベースによって返されるデータが変更される可能性があるという事実にどのように対処しますか?
  • このコードに対してユニットテストを記述する必要がありますか?
2
Dennis

メソッドの全体的な目的がデータベースからデータを取得することである場合、データベースのモックを作成するメソッドの自動テストを作成することは明らかに役に立たないため、テストの全体的な目的が妨げられます。

さらに、本番システムに対するテストを記述することはあまり意味がありません。テスト環境と本番環境 さまざまな理由で常に分離する必要があります 。安定したデータを含むテストデータベースをセットアップすると、問題は解消します。

コメントへのいくつかのコメント:

  • 軽量のDBシステムを使用していない場合は、いくつかのテストのためだけにテストデータベースを設定しても、努力する価値はありません。しかし、より大きなDBシステムでは、通常、異なるスキーマとデータ領域を並べて実装し、スキーマをリポジトリのパラメータにして、開発データベースに安定したテスト領域を実装することができます。

  • コード全体がまだ流動的である場合、正確な結果をテストすることは今のところ時期尚早かもしれません。ただし、SQL構文が正しい場合、またはクエリが最小数のレコードを提供する場合は、db接続の動作などをテストすることはすでに理にかなっている可能性があります。それがあなたの状況であれば、それを正確にテストしてください。

7
Doc Brown

このコードに対してユニットテストを記述する必要がありますか?

いいえ、ユニットテストは完全に分離して実行する必要があり、メソッド内でロジックをテストするためです。代わりに、自動テストを作成します。

リポジトリレベルで何をテストする必要がありますか?

自動テストでは次のことができます。

  • プログラムでデータを挿入しますTEST db instance;
  • リポジトリコードを呼び出します。
  • 取得したデータをアサートします。

ライブデータベースによって返されるデータが変更される可能性があるという事実にどのように対処しますか?

上記と同じ答え。

2
Emerson Cardoso

setCoefficients()メソッドはありますか?もしそうなら、私がしたいのはこれです。 (警告:物議を醸しています。私のポイントが損なわれる可能性があります...)

  1. TEST dbをクリアします。
  2. コードを使用してデータを挿入します。
  3. 取得して比較します。

これは「単体テスト」ではありません。しかし、他の答えはどちらでもありません。これはあなたが(通常)本当に知りたいことをテストします:あなたが書くものがあなたが読むものであることを。そして、あなたはエラーケースをテストする必要があります。コード内の偽のモデルが処理されます。データがa、b、cという名前の列を持つSQL dbにあるかどうか本当に気にしますか? 通常はありません

2
user949300

他の回答に加えて、テストを複数の部分に分割することをお勧めします。オブジェクトを永続化するという非常に広範な動作をテストするだけでなく、オブジェクトをデータに変換する方法やデータベースとの接続の一部など、個々のことをテストすることをお勧めします。

0
RabbitBones22