2012-03-23 10 views
3

私は、私のjunitテストで別の方法で隠されたいくつかの値をテストしたいという問題がありました。どのようにしてそのようなことになりますか?モキトと?サブクラス化?ここでテストセットメソッド内でアサーションを使用して単体テストを書く方法は?

問題:

public class MyService extends AbstractService { 

public ResponseObject insert(SomeData data) { 
    Request request = createRequest(data); 
    Response response = new Response(); 
    callService(request, response); 
    return createResponseObject(response); 
} 

protected void callBackendService(...) { 
    ... 
} 
} 

どのように

callBackendService()
メソッドに渡された値をテストするのでしょうか?

サブクラス化を使用するよりもエレガントな方法がありますか?それだけで、実装の詳細であれば

MyService service = new MyService() { 

    @Override 
    protected void callBackendService(...) { 
     assertEquals(...); 
     ... 
    } 
} 

よろしく、

マイク

+2

「callService」をテストしてください。 'レスポンス'を作成し、そのメソッドを呼び出してテストします。 – khachik

+1

はcallService()がcallBackendService()になっていますか? – Sean

答えて

1

はcallBackendServiceを()をテストしないでください。それが非常に複雑な場合、それはそれ自身のテストであり、それを別のクラスにリファクタリングする価値がある。

2

あなたのパブリッククラスを単体テストする必要があるという考えがあります。したがって、から返されたResponseObjectにあなたの主張をしてください。

それ以外の場合は、Mockitoのような模擬フレームワークを使用して、callBackendService()メソッドを独自のクラス(例:ServiceCaller)に絞り込むことができます。次に、模擬ServiceCallerオブジェクトを作成し、それに渡すパラメータをverfiyにすることができます。

このような何か...

public class ServiceCaller { 

    public callBackendService(Request request, Response response) { 
     ... 
    } 

} 

次に、このようになるはずですあなたのクラス...

public class MyService extends AbstractService { 


    private ServiceCaller serviceCaller; 

    public ResponseObject insert(SomeData data) { 
    Request request = createRequest(data); 
    Response response = new Response(); 
    serviceCaller.callBackendService(request, response); 
    return createResponseObject(response); 
    } 

    public setServiceCaller(ServiceCaller caller) { 
     this.serviceCaller = caller;   
    } 

} 

そして最後にMockitoのテストは、このような気にいらないです...

@Test 
public void testInsert() throws Exception { 

    // object to test 
    MyService ms = new MyService(); 

    // test input values 
    Request req = new Request(); 

    Response resp = new Response(); 

    // create a mock class and inject it into your test class 
    ServiceCaller sc = mock(ServiceCaller.class); 

    ms.setServiceCaller = sc; 

    // execute the method under test 
    ms.insert(req, resp); 

    // now you can see if your mock was called with the expected params 
    verify(sc).callBackendService(req, resp); 
} 

簡潔さのためにInterfacesなどを使って良いデザインを省略しましたが、あなたはそのアイデアを得るでしょう。

1

注:私は、独自のクラスの1つにcallBackendService()

も、そのクラスのメソッドの間の相互作用ではなく、テスト動作にもっと焦点を当てるべきであるcallService()を想定しています。テストの振る舞い(あなたがしようとしているものとは対照的に)は、あなたのテストがあなたの実装と緊密に結びついていないようにします。たとえば、callBackendService()メソッドをテストし、後でそのクラスの実装の詳細を変更しようとすると、テストが中断されます。代わりにメソッドの動作をテストすることに焦点を当てている場合は、いつでもその特定の呼び出しを変更することができ、実際に目的の動作を壊した場合にのみテストが中断します。

さらに、挿入メソッドについて詳しく説明します。他のテストでcreateRequest()メソッドとnew Response()コンストラクタの動作をテストした場合、期待通りの結果が得られていることはすでにわかっています。したがって、callBackendService()メソッドが実際には何も新しいものをテストしていないと予想されるパラメータを受け取ったことを確認する別のテストを作成します。あなたは何をすべき

insert()メソッドを呼び出すの結果をテストしています。

だからあなたの質問への答えは、callBackendService()メソッドに引数をテストしていないされています。

関連する問題