3

この問題は例を挙げて最もよく説明されていると思います。

public class MyService {
    private OtherService theOther;
    public void setTheOther(OtherService srv) { theOther = srv; }

    public void myBusinessStuffFor(int id) {
        theOther.applyToAllWith(id, new OtherService.Action() {
            public void apply(Object whatever) {
                doTheHardBusinessStuffWith(whatever);
            }
        }
    }

    private void doTheHardBusinessStuffWith(Object whatever) {
        // here the business stuff provided by MyService
    }
}

public interface OtherService {
    void applyToAllWith(int id, Action action);

    public interface Action {
        void applyOn(Object whatever);
    }
}

とてもまとまりがあるので、私はこのパターンが好きです。アクションインターフェイスは、それらのサービスとペアになっています。ビジネスロジックは、多くのクラスで乱雑ではありません。サブクラスはアクションにデータを提供するだけであり、忙しくする必要はありません。ここから採用しました(http://jamesladdcode.com/?p=12)。問題は、otherServiceをモックした場合に、「doTheHardBusinessStuffWith(Objectwhatever)」メソッドの動作をテストするための適切なソリューションが見つからなかったことです。モックでは、ビジネスメソッドがどのように呼び出されるかを気にする必要があります。しかし、どうすればこれを行うことができますか。私はmockitoを使用し、すでにArgumentCaptureで試しました。しかし、ArgumentCaptureを悪用しているため、正しく感じられません。

クラスMyService.myBusinessStuffFor(int id)で使用されているパターンに名前があるかどうか(戦略パターンですか)を知りたいですか?しかし、私の主な質問は、OtherServiceのモックでこのコードをテスト可能にする方法です。

4

2 に答える 2

1

この場合、他のサービスは実際にはビジネスサービスではありません。その唯一の責任は、指定されたIDからオブジェクトを検索し、これらのオブジェクトに指定されたアクションを適用することです。機能的には、これは次のコードと同等です。

Set<Object> objects = otherService.getObjectsWithId(id);
for (Object o : objects) {
    doTheHardBusinessStuffWith(o);
}

保護しdoTheHardBusinessStuffWithます。このメソッドの単体テストを作成します。これは最も重要な単体テストです。ビジネスロジックをテストする単体テストです。

本当に単体テストが必要myBusinessStuffForな場合は、オブジェクトのセットから構築され、指定されたアクションをオブジェクト内のすべてのオブジェクトに適用するモックOtherServiceを作成します(つまり、このモックを自分で実装します)。セットする。メソッドがモックされ、モックOtherServiceが注入されるMyService場所の部分的なモックを作成します。部分的なモックをdoTheHardBusinessStuffWith呼び出し、オブジェクトのセットのすべてのオブジェクトで呼び出されたことを確認します。myBusinessStuffFordoTheHardBusinessStuffWith

于 2012-01-20T08:46:24.540 に答える
-1

あなたはOtherServiceのモックについて話します。どのモックフレームワークを使用しているかわかりません。ただし、applyToAllWithメソッドに渡されるアクションのapplyOnメソッドを呼び出すだけのモックを作成し、モックオブジェクトを引数として渡すことができるはずです。たとえば、mockitoでは、これは次のようにスタブされます。

doAnswer( new Answer<Object>(){
    public Object answer( InvocationOnMock invocation ){
        ((Action) invocation.getArguments()[ 1 ]).applyOn( mockObject );
        return null;
}}).when( mockOtherService ).applyToAllWith( anyInt(), any( Action.class ));

ここで、はインターフェイスmockOtherService用に作成したモックであり、に渡すモックはどれでもかまいません。OtherServicemockObjectdoTheBusinessHardStuffWith

于 2012-01-20T08:45:34.917 に答える