Die kurze Antwort lautet "Nein". Der interessantere Teil ist, warum / wie diese Situation entstehen könnte.
Ich denke, die Verwirrung entsteht, weil Sie versuchen, strenge Testpraktiken (Komponententests gegen Integrationstests, Verspotten usw.) für Code einzuhalten, der anscheinend nicht strengen Praktiken entspricht.
Das heißt nicht, dass der Code "falsch" ist oder dass bestimmte Praktiken besser sind als andere. Nur, dass einige der Annahmen der Testpraktiken in dieser Situation möglicherweise nicht zutreffen und es hilfreich sein kann, bei Codierungs- und Testpraktiken ein ähnliches Maß an "Strenge" zu verwenden. oder zumindest anzuerkennen, dass sie möglicherweise nicht ausgeglichen sind, was dazu führt, dass einige Aspekte nicht zutreffen oder überflüssig werden.
Der offensichtlichste Grund ist, dass Ihre Funktion zwei verschiedene Aufgaben ausführt:
- Nachschlagen
Person
anhand ihres Namens. Dies erfordert Integrationstests, um sicherzustellen, dass es gefunden werden kannPerson
Objekte gefunden werden die vermutlich an anderer Stelle erstellt / gespeichert wurden.
- Berechnung, ob a
Person
alt genug ist, basierend auf ihrem Geschlecht. Dies erfordert einen Komponententest, um sicherzustellen, dass die Berechnung wie erwartet ausgeführt wird.
Wenn Sie diese Tasks zu einem Codeblock zusammenfassen, können Sie keinen ohne den anderen ausführen. Wenn Sie die Berechnungen in einer Einheit testen möchten, müssen Sie nach a suchen Person
(entweder aus einer realen Datenbank oder aus einem Stub / Mock). Wenn Sie testen möchten, ob die Suche in den Rest des Systems integriert ist, müssen Sie auch eine Altersberechnung durchführen. Was sollen wir mit dieser Berechnung machen? Sollten wir es ignorieren oder überprüfen? Das scheint genau das Problem zu sein, das Sie in Ihrer Frage beschreiben.
Wenn wir uns eine Alternative vorstellen, können wir die Berechnung selbst durchführen:
def is_old_enough?(person)
if person.male?
return person.age > 21
else
return person.age > 18
end
end
Da es sich um eine reine Berechnung handelt, müssen keine Integrationstests durchgeführt werden.
Wir könnten auch versucht sein, die Suchaufgabe separat zu schreiben:
def person_from_name(name = 'filip')
return Person::API.new(name)
end
In diesem Fall ist die Funktionalität jedoch so Person::API.new
ähnlich , dass ich sagen würde, dass Sie stattdessen diese verwenden sollten (wenn der Standardname erforderlich ist, sollte er besser an einer anderen Stelle gespeichert werden, z. B. als Klassenattribut).
Wenn Sie Integrationstests für Person::API.new
(oder person_from_name
) alles schreiben, worüber Sie sich Gedanken machen müssen, ist, ob Sie die erwarteten Ergebnisse zurückerhalten Person
. Alle altersbezogenen Berechnungen werden an anderer Stelle durchgeführt, sodass Ihre Integrationstests sie ignorieren können.