すべての依存関係を適切にテストすることは依然として重要ですが、ジェフリーファウストが言ったように、それは統合テストの領域にあります。
単体テストの最も重要な側面の1つは、テストを信頼できるものにすることです。合格したテストが本当に良いことを意味し、失敗したテストが実際に本番コードの問題を意味することを信用しない場合、テストは可能な限り有用ではありません。
テストを信頼できるものにするためには、いくつかのことを行う必要がありますが、この回答では1つだけに焦点を当てます。もし開発者のすべてが簡単にコードをチェックインする前にそれらを実行できるように、彼らは実行しやすいことを確認する必要があります。「簡単に実行することは、」あなたのテストはすぐに実行することを意味し、それらを行かせるために必要な一切の広範な構成や設定がありません。理想的には、誰でもコードの最新バージョンをチェックアウトし、すぐにテストを実行し、合格することを確認できるはずです。
他のもの(ファイルシステム、データベース、Webサービスなど)への依存関係を抽象化することで、構成の必要性を回避でき、あなたや他の開発者は「ああ、テストは失敗したから」と言いたくなる状況になりにくくなりますネットワーク共有を設定します。まあ、後で実行します。」
一部のデータを使用して何を行うかをテストする場合、そのビジネスロジックコードの単体テストでは、そのデータの取得方法を考慮する必要はありません。データベースなどのサポートに依存せずにアプリケーションのコアロジックをテストできることは素晴らしいことです。あなたがそれをしていないなら、あなたは逃しています。
PSテスト可能性という名目でオーバーエンジニアリングすることは間違いなく可能であると付け加えます。アプリケーションのテスト駆動は、それを軽減するのに役立ちます。しかし、いずれにしても、アプローチの実装が不十分であっても、アプローチの有効性が低下することはありません。「なぜ私はこれをしているのですか?」開発中。
内部の依存関係に関する限り、物事は少し濁っています。私がそれについて考えるのが好きなのは、間違った理由でクラスが変わるのを可能な限り防ぐことです。このような設定があれば...
public class MyClass
{
private SomeClass someClass;
public MyClass()
{
someClass = new SomeClass();
}
// use someClass in some way
}
私は通常、どのようSomeClass
に作成されるかを気にしません。使いたいだけです。SomeClassが変更され、コンストラクターへのパラメーターが必要になった場合、それは私の問題ではありません。これに対応するためにMyClassを変更する必要はないはずです。
さて、それは設計部分に触れているだけです。単体テストに関する限り、他のクラスからも自分を守りたいと思っています。MyClassをテストする場合、外部依存関係がないこと、SomeClassがデータベース接続または他の外部リンクを導入していないことを知っているのが好きです。
しかし、さらに大きな問題は、メソッドの結果の一部がSomeClassのメソッドの出力に依存していることも知っていることです。SomeClassをモック/スタブ化せずに、その入力を需要に応じて変更する方法がないかもしれません。運が良ければ、SomeClassから正しい応答をトリガーするようにテスト内で環境を構成できるかもしれませんが、そのようにすると、テストが複雑になり、テストが脆弱になります。
MyClassを書き換えてコンストラクターでSomeClassのインスタンスを受け入れると、(モックフレームワークまたは手動モックを使用して)必要な値を返すSomeClassの偽のインスタンスを作成できます。私は、一般的にはありません持っている。この場合、インタフェースを導入します。そうするかどうかは、多くの点で選択する言語によって決定される個人的な選択です(たとえば、インターフェイスはC#でより可能性が高いですが、Rubyでは間違いなく必要ではありません)。