logo

Unittesting in ObjectiveC

Unittesting ist ein nützliches Werkzeug um eine hohe Qualität von Software zu gewährleisten. Auch in ObjectiveC ist es möglich, Unittests zu verwenden, mit dem SenTestingKit.

Einfache Tests

STAssertTrue([object execute], @"execution failed");
STAssertEquals(@"A teststring", @"A teststring", @"Both strings should be equal");

Der letzte Parameter ist immer die Meldung, die ausgegeben wird, sollte der Test fehlschlagen. Hier eine Übersicht der möglichen Tests (entnommen aus SenTestCase.h):

STAssertNil(a1, description, ...)
STAssertNotNil(a1, description, ...)
STAssertTrue(expression, description, ...)
STAssertFalse(expression, description, ...)
STAssertEqualObjects(a1, a2, description, ...)
STAssertEquals(a1, a2, description, ...)
STAssertEqualsWithAccuracy(left, right, accuracy, description, ...)
STAssertThrows(expression, description, ...)
STAssertThrowsSpecific(expression, specificException, description, ...)
STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...)
STAssertNoThrow(expression, description, ...)
STAssertNoThrowSpecific(expression, specificException, description, ...)
STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...)
STFail(description, ...)
STAssertTrueNoThrow(expression, description, ...)
STAssertFalseNoThrow(expression, description, ...)

Mock Objekte

Es ist weiterhin möglich, Objekte zu mocken, d.h. ein Pseudo-Objekt zu generieren, dessen Verhalten während des Testes man konkret bestimmt. Damit lässt sich die Funktionalität einer einzelnen Klasse testen, ohne alle Abhängigkeiten mit hineinzuziehen.

Das OCMock Framework ist eine Möglichkeit, Mock-Objekte zu erzeugen. Die Verwendung ist nicht sehr kompliziert:

id mock = [OCMockObject mockForClass:[MyClass class]];
[[mock stub] myMethod:@"my value"];
[[[mock expect] andReturn:@"expected result"] myOtherMethod:@"some value"];
[myObject setDependency:mock];
[myObject execute];
[mock verify];

Dieses Beispiel zeigt zwei Anwendungen. Erstens: stub, zweitens: expect. Ein stub besagt lediglich, dass das Mock-Objekt auf diese Methode reagiert. Wird ein expect angegeben, erwartet das Mock-Objekt, dass diese Methode mit den angegebenen Parametern ausgeführt wird. Geprüft wird dies anschließend mit verify. Auch stub-Methoden können eine Rückgabe mit andReturn enthalten.

Dabei ist es unproblematisch, Objekte zurückzugeben. Sollen einfachere Datentypen zurückgegeben werden, erfolgt dies mittels andReturnValue.

BOOL myValue = YES; 
[[[mock expect] andReturnValue:myValue] myMethod:@"parameter"];

Je nach Systemvoraussetzungen und Compiler-Einstellungen kann es sein, dass der Wert mit expliziter Typenangabe erfolgen muss oder mittels __typeof__, solange das Problem im Framework nicht behoben wird. (siehe Forendiskussion).

[[[mock expect] andReturnValue:[NSValue value:&myValue withObjCType:@encode(BOOL)]] execute];
[[[mock expect] andReturnValue:[NSValue value:&myValue withObjCType:@__typeof__(myValue)]] execute];

 

Dies nur als kleinen Einstieg in OCMock, es gibt auf der Webseite weitere Beispiele.