2

まず、私はを使用Scalaしますが、どのJavaアプローチでもおそらく機能します。

データベースに接続されたアプリケーションがあり、データベースを変更せずに、またはデータベースがオフラインの場合に、テストを実行してアプリケーションを開発したいと考えています。

たとえば、データベースに接続する大規模なクラス(またはモジュール)がありますが、これらすべてのことを実行しますか?外部からそのクラスまたはそのパラメーターにアクセスするにはどうすればよいですか?

たとえば、クラスを正常に実行したいが、の代わりに、statement.executeUpdate( sql )このprintln( "Did: " + sql )テストで最初のメソッドを呼び出さずに、を実行したい場合です。

明らかに、1つの方法は、これらのステートメントを単純に置き換えるか、ファイル全体をコピーして置き換えることです。しかし、エラーが発生しやすく、元に戻すと何かを忘れてしまう可能性があります。さらに、それは非常に冗長です。

この問題にどのように取り組むか?どのようにそれを行うのJUnitですか?

免責事項:「クラスのパラメータ化」のような解決策は使用しないでください。コンストラクターにパラメーターをほとんど持たせたくないので、呼び出すたびにすべてを指定する必要はありません。テストクラスは私のアプリケーションでは二級市民であり、実際のクラス/実際の開発にはほとんどまたはまったく影響を与えないはずです。

4

4 に答える 4

5

クラス内のすべてのデータベースメソッドを含むインターフェイスを定義する必要があります。次に、既存のデータベースクラスがそのインターフェイスを実装していることを確認します。

これでインターフェースができたので、クラスをモックするか、テスト用のスタブクラスを開発することができます。スタブクラスは、SQLまたは必要なものを出力するだけです。モッククラスはより強力であり、ビジネスロジックが正しく機能していることを確認するために使用できます。

最後のステップは、データベースを使用するすべての場所で、コンストラクターでインターフェースを受け入れるようにすることです。例えば

public class ClassThatUsesTheDatabase {

    public ClassThatUsesTheDatabase(DatabaseProvider provider) {
      //...
    }
}

DatabaseProviderインターフェースはどこにありますか。ClassThatUsesTheDatabaseこれにより、スタブまたはモックでテストできます。本番環境では、具体的な実装を使用してこのクラスを構築します。

私の意見では、これが外部リソースに依存するアプリケーションを作成するための唯一の正しい方法です。


あなたの質問を読み直した後、私は次の段落について心配しています:

免責事項:「クラスのパラメータ化」のような解決策は使用しないでください。コンストラクターにパラメーターをほとんど持たせたくないので、呼び出すたびにすべてを指定する必要はありません。テストクラスは私のアプリケーションでは二級市民であり、実際のクラス/実際の開発にはほとんどまたはまったく影響を与えないはずです。

テストクラスは二級市民ではありません。コードの品質を真剣に考えているのであれば、これらは本番コードと同じくらい重要です。そして、はい、ユニットテストに適したものにするためにプロダクションコードを設計しなければならないことがよくあります。これは避けられません。ただし、そのメリットは非常に大きいです。

于 2013-02-24T08:20:01.313 に答える
4

「クラスのパラメータ化」のような解決策はありません。

その後、あなたはそれを間違っています。データベース呼び出しは、ダミーの実装に簡単に置き換えることができるモックオブジェクトで行う必要があります。とにかくexecuteStatementを使用している場合は、SQLインジェクションに対して脆弱である可能性があります。アプローチを再考する必要があります。

于 2013-02-24T08:02:37.993 に答える
1

個人的には、ボブおじさんと一緒にいます。すべてのDBインタラクションをプログラム内のクラスに分離して、テストで別のものに置き換えることができるようにする必要があります。また、パラメーター化したくない場合でも、ケーキパターンと依存性注入があります。

ここで、データベースと通信するライブラリへの依存関係をハードコーディングすることを主張する場合でも、実行できることが1つあります。それはデータベースをモックすることです。データベースインターフェイスを実装する必要があるため、これを行うのは難しいかもしれません。

私は実際にプロジェクトでそれを行いましたが、それはHTTP + JSONに基づくNoSQLデータベースであったため、データベースのモックはWebサーバーのモックと同じくらい簡単でした。

次に、テスト中に偽のデータベースをポイントするだけで、準備は完了です。

それでも、コードをテストしやすくすると、コードが改善されます。

于 2013-02-24T08:23:42.297 に答える
0

JUnit(およびその他の主流の単体テストフレームワーク)では、ソリューションの標準的な範囲は、ある種の依存性注入であり、これには、いわゆる「クラスのパラメーター化」が含まれます。王道はありません、申し訳ありません:-)ただし、本番コードの中断を最小限に抑えるか回避するために、さまざまな方法でそれを行うことができます。

この種の問題に対処する通常の方法は、データベースアクセスコードを抽出し、それをモック可能なインターフェイスの背後に隠すことによって、テストするロジックをデータベースアクセスコードから分離することです。次に、テスト対象のコードで、のようなステートメントがのようなstatement.executeUpdate(sql)呼び出しに置き換えられますdataAccessor.updateFooBar(foo, bar)。そして、これらの呼び出しを行うデータアクセサーオブジェクトは、何らかの方法でクラスに挿入されます-これはオプションのコンストラクターパラメーターである可能性があり、デフォルト値が実際のデータアクセサーオブジェクトであるフィールドである可能性がありますが、設定するためのパッケージアクセス付きのセッターがありますユニットテスト中のモックデータアクセサー..

于 2013-02-24T08:22:35.217 に答える