短い答えは「いいえ」です。より興味深い部分は、この状況が発生する理由/方法です。
厳密な慣行に従わないコードの厳密なテスト慣行(単体テストと統合テスト、モックなど)を順守しようとしているため、混乱が生じていると思います。
それは、コードが「間違っている」とか、特定のプラクティスが他のプラクティスより優れているということではありません。単純に、テストプラクティスによって行われた仮定の一部がこの状況に当てはまらない場合があり、コーディングプラクティスとテストプラクティスで同様のレベルの「厳格さ」を使用すると役立つ場合があります。または、少なくとも、それらが不均衡である可能性があることを認めるため、いくつかの側面が適用不能または冗長になる可能性があります。
最も明白な理由は、関数が2つの異なるタスクを実行していることです。
- 見上げる
Person
その名前に基づいて。これには、Person
おそらく他の場所で作成/保存されたオブジェクトを検出できることを確認するために、統合テストが必要です。
Person
性別に基づいて、a が十分に古いかどうかを計算します。これには、計算が期待どおりに実行されることを確認するための単体テストが必要です。
これらのタスクを1つのコードブロックにグループ化することにより、他のタスクなしでは実行できません。計算を単体テストする場合、Person
(実際のデータベースまたはスタブ/モックから)ルックアップする必要があります。ルックアップがシステムの残りの部分と統合されていることをテストする場合、年齢の計算も実行する必要があります。その計算で何をすべきでしょうか?無視するか、確認する必要がありますか?それはあなたがあなたの質問で説明している正確な苦境のようです。
代替案を想像する場合、独自の計算を行うことができます。
def is_old_enough?(person)
if person.male?
return person.age > 21
else
return person.age > 18
end
end
これは純粋な計算なので、統合テストを実行する必要はありません。
ルックアップタスクを個別に記述したい場合もあります。
def person_from_name(name = 'filip')
return Person::API.new(name)
end
ただし、この場合、機能は非常に近いためPerson::API.new
、代わりにそれを使用する必要があります(デフォルト名が必要な場合は、クラス属性などの別の場所に保存する方が良いでしょうか?)
Person::API.new
(またはperson_from_name
)統合テストを作成する際に注意する必要があるのは、期待通りの結果が得られるかどうかだけですPerson
。年齢ベースの計算はすべて他の場所で処理されるため、統合テストではそれらを無視できます。