Sonntag, 9. August 2020
Seite wählen

"Local Mock Variables" — Ein dritter eleganter Weg in JMockit?

1. Mock-Deklaration als Class Field

Wie oben beschrieben genügt z.B. ein vorangestelltes @Mocked, um für eine Class Field Declaration zur Laufzeit z.B. eine Mock-Instanz anzubieten. JMockit unterstützt hier zwei Varianten:

a. Mock-Deklaration direkt in der Test-Klasse
b. Mock-Deklaration im Expectations-Block

Eine kurze Einschätzung im Anschluss an die beiden Beispiele. Zunächst exemplarisch ein Snippet für

a. Mock-Deklaration direkt in der Test-Klasse

Der zu mockende Java Type wird direkt als Class Field deklariert (Zeile 3) und in einer üblichen Testmethode genutzt (Zeile 14):

[java highlight=“3″]
public final class MyTest
{
@Mocked
final IDatabase mockedDatabase;

final IUser user = …
final IPassword password = …

// usual test code …
@Test
public void login_should_accept()
{
// …
final boolean loginStatus = mockedDatabase.login( user, password );
// and so on …

assertThat( loginStatus ).isTrue(); // [2]
}
}
[/java]

b. Mock-Deklaration im Expectations-Block

Die zweite Variante ist eine Deklaration als Local Field in einem Expectations-Block:

[java highlight=“4″]
:
new Expectations()
{
@Mocked
final IDatabase mockedDatabase;

{
mockedDatabase.login( user, password );
result = true;
// …
}
}
:
[/java]

In Zeile 4 wird via @Mocked für mockedDatabase eine automatische Mock-Handhabung deklariert. In den Zeilen 8+9 – im Initialisierungsblock – werden exemplarisch in üblicher Art und Weise Expectations definiert.

Tipp:

Die @Mocked-Annotation könnte im Expectations-Block weggelassen werden, da hier Field Declarations per Default als @Mocked angenommen werden. Bei expliziter z.B. @NonStrict-Deklaration ist diese als „Non-Default“ immer anzugeben (bei der Variante „a. Mock-Deklaration direkt in der Test-Klasse“ ist ebenfalls die @Mocked-Annotation anzugeben, da es dort üblicherweise einen Mix mit den „normalen“, nicht gemockten Class Fields – hier in Zeile 6+7 IUser, IPassword – geben kann).

Einschätzung:
Im Rahmen der grundsätzlichen Ziel-Setzung „Test Isolation“ hat die Deklarations-Art 1.a. den Nachteil, dass derart gemockte Instanzen für alle Test-Methoden identisch sind – es wird nur ein(!) Mock erzeugt. Es könnten Seiteneffekte und Abhängigkeiten zwischen den Tests entstehen (diese Gefahr kennt man z.B. bei sporadisch brechenden Tests: ein Test für sich allein ausgeführt ist stets in Ordnung, in Kombination und mit variablen Reihenfolgen anderer Testmethoden der Testklasse funktioniert er mal und mal nicht).

Die Variante 1.b. mit der Deklarations als Local Field innerhalb des Expectations-Block bewährt sich und bietet nachhaltig stabilere Tests.

Es folgt eine Skizze für „2. Mock-Deklaration als Method Parameter„.