1

Facade(Singleton)を使用して作成された静的メンバーを持つJavaクラスがあります。

クラス A は InterfaceA を実装します {

 private static DataStore db = DataStoreFacade.getInstance("BDB"); // シングルトン インスタンス

  public void save(最終文字列キー、最終文字列値) {
     デシベル保存 (キー、値);
  }
};

ここで、クラス A は Web サービス (ステートレス Bean) のメンバー変数として使用されます。

DataStore インスタンスをオーバーライドする方法がないため、EasyMock を使用してこのコードをテストすることはできません。

2 つのオプションがあります。

  1. コンストラクターに、db メンバー変数に設定される DataStore のインスタンスを取得させます。問題は、どのデータストア インスタンスが作成されたかを webservice クラスに認識させたくないことです。

  2. 追加の保護された Set メソッドを提供して、db オブジェクトをオーバーライドします。これは、DataStore の Easy Mock オブジェクトを作成し、メンバー変数をオーバーライドする場所で使用したものです。正しい設計か。

他の可能性は何ですか?

4

4 に答える 4

0

さて、元のコードすでにテスト可能です。JMockitを使用したユニットテストは次のとおりです。

@Test
public void testSave(final DataStore mockDb)
{
    final String key = "aKey";
    final String value = "aValue";

    new A().save(aKey, aValue);

    new Verifications()
    {{
        mockDb.save(key, value);
    }};
}

必要に応じて、DataStoreFacadeクラスもモックすることができます。

于 2010-07-05T15:10:26.183 に答える
0

置き換えインスタンス パターンを使用...

http://goodcoffeegoodcode.blogspot.com/2010/01/supercede-instance-pattern.html

于 2010-02-03T18:59:08.460 に答える
0

db メンバーを保護し、テスト プロジェクトでそれを継承してそのメンバーをオーバーライドしないのはなぜですか。

project 
{
    Class A
    {
        protected static db = ...
        public void Save(...) { ... }
    }
}

test_project
{
    Class B : A
    {
        protected override static db = ... (create test db)
    }

    Class testB
    {
        public A a;

        public void Setup()
        {
            this.a = new B();
        }

        public void TearDown()
        {
            // delete a
        }

        public void TestSaveKey()
        {
            // test a
        }
    }
}

コード/ライブラリの消費者からはまだ隠されています。テスト オブジェクトは製品コードを乱雑にすることはなく、動作は製品バージョンであるかのようにテストされます。

ただし、各テストの後に適切にクリーンアップされていない場合、db オブジェクトの静的メンバーを使用すると、テストで問題が発生する可能性があることに注意してください。

  • あなたはおそらくすでにこれを知っていると思いますが、完全を期すために言っています。
于 2010-07-05T15:24:45.320 に答える
0

あなたはそうです、それはテスト容易性に悪いです。依存性注入を使用し、静的変数を使用しないでください。


public class A implements InterfaceA {

  private DataStore db;

  public A(DataStore db) {
    this.db = db;
  }

...

}

注入またはビルドするには、依存性注入フレームワーク (Spring など) を使用するか、ブートストラップ ファクトリ コードのどこかにオブジェクトをビルドします。

生産コード:


new A(DataStoreFacade.getInstance("...");

テストコード:


public void test_xxx(){
  DataStore db = EasyMock.createMock(DataStore.class);
  //... do some expectations and replay(db)
  InterfaceA a=new A(db);
  //...

}

于 2010-02-03T22:15:31.160 に答える