0

私は常に、クラスに保護されたメソッド getDate() があり、テスト目的でオーバーライドした方法で Dates をテストしてきました。例:

public class MyClass {
    protected Date getDate(){
        return new Date();
    };
}

テスト:

MyClass myclass = new MyClass(){
    @Override
    protected Date getDate(){ 
        return new Date(1234567890);
    }
};

それは今日まで十分でしたが、次の問題が発生しました: 一度インスタンス化したいクラスがあるので、シングルトン パターンを使用します。

public static Something getInstance() {
    if (instance == null) {
        instance = new Something();
    }

    return instance;
}

問題は、この方法でオブジェクトを作成する必要があることです。Something.getInstance() - オブジェクトはそのメソッド内で作成されます。getInstance 内で getDate メソッドをオーバーライドすることはできません。意味がないからです (実際のインスタンスが必要な場合もあれば、インスタンスをテストする場合もあります)。これは私に質問をもたらします:そのような状況で日付をテストするにはどうすればよいですか?

4

4 に答える 4

1

お気づきのように、単純な古い Java シングルトンを使用するたびに、テスト不可能なコードが作成されます。

クラスのインスタンスを 1 つだけ持つ方法は他にもあります。シンプルなものから、一度作成するだけです:)SpringのようなIoCフレームワークを使用して、それらを気にかけます。

Misko Hevery's guide to writing testable codeのグローバル状態に関するセクションをご覧になることをお勧めします。

于 2013-03-28T09:49:31.347 に答える
1

Singleton パターンがどうしても回避できない場合に限り、 PowermockSomethingを使用してクラスの構築をモックできます。

//create mock instance,     
Something mockSomethingInstance = createMock(Something.class);
//create your Date instance to return
Date d = new Date();
when(mockSomethingInstance.getDate()).thenReturn(d);

作成したインスタンスを常に返すには、Something クラスのコンストラクターをモックする必要があります (ただし、これを行うと、クラスの他のすべての構成もオーバーライドされることに注意Somethingしてください。ただし、この場合、これはシングルトンであるため、問題ないようです)。 :

expectNew(Something.class).andReturn(mockSomethingInstance); 

また、Powermock は静的関数呼び出しもモックできるSomethingため、クラスの getInstance 関数もモックできます。

//mock the static functions
mockStatic(Something.class);          

expect(Something.getInstance()).andReturn(mockSomethingInstance);
//have to replay the class in order to work
replay(IdGenerator.class); 

ただし、クラス自体の動作をテストしたいので、部分的なモックを行いたいと思います。しかし、これはますます醜くなり始めています...

全体として、シングルトンを使用する前によく考えてください - シングルトンは単純に見えますが (もちろん、onlz のように見えます...)、長期的には、すぐに悪夢に変わる可能性があります... Spring を使用すると、同じことを行うよりクリーンな方法です、多くの頭痛の種を救います。

于 2013-03-28T09:49:57.110 に答える
0

Capture を使用する必要があるのは (EasyMock がオプションであると仮定して) 多くのように思えます。

于 2013-03-28T09:46:31.673 に答える
0

シングルトンに getDate() メソッドを配置すると、グローバル状態として知られる状態になるため、テスト目的でモックアップすることはほとんど不可能になります。唯一の選択肢は、テスト フレームワークを使用するか、クラスを「真の」シングルトンにならないように変更し、他の方法でそのインスタンスを 1 つだけインスタンス化できるようにすることです。後者のオプションが正しいアプローチであり、この場合シングルトンを使用すべきではないと主張します。

于 2013-03-28T09:49:19.667 に答える