2016-08-23 6 views
4

私はすでに定義された別の方法の特殊化と見なすことができる方法に取り組んでいます。ここで説明するサンプルコードです:既にテスト済みの別のメソッドに依存するメソッドをテストするにはどうすればよいですか?

public class ProductService { 

    public void addProduct(Product product) { 
     //do something 
    } 

    public void addSpecialProduct(Product product) { 
     addProduct(product); 
     //do something after 
    } 

} 

私はすでにかなり複雑でaddProductのため、私が持っているテストをコピーする必要はありません。私が望むのは、私がaddSpecialProductのテストを定義するときです。私はプロセス内でaddProductも呼び出していることを確認しています。これが2つのクラスのコラボレーションの問題だった場合、コラボレーターを嘲笑させ、ターゲットメソッドが呼び出されたことを確認して(必要に応じてスタブする)ことは簡単です。ただし、2つのメソッドは同じクラスに属します。しかし、私はこのアプローチは何とかユニットテストの目的に反しか思ったんだけど

public void testAddSpecialProduct() { 
    //set up code 
    ProductService service = spy(new DefaultProductService());  
    service.addSpecialProduct(specialProduct); 
    verify(service).addProduct(specialProduct); 
    //more tests 
} 

は、私が今考えていることは、私がテストしてるオブジェクトのようなものをスパイすることです。この問題に関する一般的なコンセンサスは何ですか?

+1

あなたは、テストユーティリティメソッドで 'addProduct'方法のためにあなたのアサーションを入れて、複数のテストケースの間であることを再利用してもらえますか? – chrylis

+0

このクラスはビットコードの臭いが私には聞こえるので、これらの2つの機能(製品と特別な製品)を2つの別々のクラスに構成することをお勧めします。一般的な「追加」と「特殊な追加」は単一の責任を負います。 – kuhajeyan

+0

@chrylis実際には妥当と聞こえる、はい。以前は似たようなことをしたことを忘れてしまった。 –

答えて

0

私はそれはあなたがあなたのユニットテストと一緒にいたいかによって異なり厳格なと思います。極端な意味では、単体テストは実装ではなく動作をテストすべきです。これは、テストを複製する必要があることを意味します(または、@chrylisの助けを借りて、一般的な機能を抽象化してヘルパーに伝えてください)。他のメソッドが呼び出されるようにするには、実装をテストする必要があります。

は、しかし現実には、私は他の十分にテストされたメソッドが呼び出されたことを確認するために、インスタンスをスパイのアイデアは良いアイデアだと思います。私の理由は次のとおりです。

1)コードを単純化します。

2)それは何が起こっているのか私にはすぐに明らかになりました。他の方法のためにテストされたものはすべて今も真実になり、余分なアサーションがあります。

ある日、他のメソッドが呼び出されないように、あなたは、実装を変更することがあり、これは、あなたのユニットテストは、人々が一般的な実装をテストしていないことにより、避けるようにしようとしているものである、失敗する原因になります。しかし、私の経験では、このような変化は、行動がとにかく変わるときにはるかに一般的です。

0

コードのリファクタリングを検討することもできます。戦略パターンを使用して、製品や特別な製品を追加する機能を実際に実装します。

public class ProductService { 

    @Resource 
    private AddProductStrategy normalAddProductStrategy; 
    @Resource 
    private AddProductStrategy addSpecialProductStrategy; 

    public void addProduct(Product product) { 
     normalAddProductStrategy.addProduct(product); 
    } 

    public void addSpecialProduct(Product product) { 
     addSpecialProductStrategy.addProduct(product); 
    } 
} 

AddProductStrategyの2つの実装があります。元のProductService.addProduct実装で何が起こったのでしょうか? 2番目の実装は最初の実装に委譲し、次に追加の作業を必要とします。したがって、各戦略を個別にテストすることができます。 2番目の戦略の実装は、最初の実装のデコレータに過ぎません。

関連する問題