最近、テストでモックオブジェクト(Javaのmockitoを使用)を使用し始めました。言うまでもなく、彼らはテストのセットアップ部分を簡素化し、Dependency Injectionとともにコードをより堅牢にしたと主張します。テストでのモックの使用
しかし、私は自分が仕様ではなく実装に対してテストを行っていることがわかりました。私はそれがテストの一部ではないと主張するという期待を設定しました。より専門的に言えば、私はSUT(テスト対象のクラス)とその共同研究者との間の相互作用をテストすることになります。そのような依存関係は、契約やクラスのインタフェースの一部ではありません!
XMLノードを扱うとき、ノードの属性値を返すメソッドattributeWithDefault()
があるとします。そうでない場合は、デフォルト値が返されます。
私は次のようなセットアップのテストをします:
Element e = mock(Element.class);
when(e.getAttribute("attribute")).thenReturn("what");
when(e.getAttribute("other")).thenReturn(null);
assertEquals(attributeWithDefault(e, "attribute", "default"), "what");
assertEquals(attributeWithDefault(e, "other", "default"), "default");
さて、ここだけではなく、私は、私がElement.getAttribute()
を使用するためにそれを必要に応じて、attributeWithDefault()
が仕様に準拠して、私はまた、実装をテストしたことをテストしましたElement.getAttributeNode().getValue()
またはElement.getAttributes().getNamedItem().getNodeValue()
の代わりに
編集:私はテストが悪いのスタイルであるという上記の仮定をしたテスト
と間違って何 、ここに私の根拠はあります。
この仕様では、どのメソッドが呼び出されるかは指定されていません。ライブラリのクライアントは、正しく実行されている限り、属性がどのように取得されたかを気にする必要はありません。実装者は、(パフォーマンス、一貫性などに関して)どのような方法であれ、代替アプローチにアクセスするための自由な治世を持つべきである。
Element
の仕様では、これらのアプローチがすべて同じ値を返すようにしています。Element
をgetElement()
という1つのメソッドインタフェースに再因子付けすることは意味がありません。使い易さのために、メソッドのクライアントは標準ライブラリの標準Element
を使用するだけです。インターフェイスと新しいクラスを持つことは、クライアントのコードを醜いものにするので、単なる愚かなIMHOです。それは価値がありません。スペックはそのままで、テストはそのままであると仮定すると、新しい開発者はコードをリファクタリングして状態を使用する別のアプローチを使用し、テストを失敗させる可能性があります。実際の実装が仕様に準拠していない場合、テストは失敗します。
共同編集者を複数の形式で公開することはかなり一般的です。仕様とテストは、どのようなアプローチが取られているかに依存すべきではありません。実装だけが必要です!
+1。動作(モック)と状態(スタブ)テストの違いを明確にしたように。 – notnoop