Frage

Ich mag ein Stück Code zu testen, das Netzwerk verwendet (die NSURLConnection Klasse, um genau zu sein). Der Code (nennen wir es NetworkManager) sieht ein bisschen wie folgt aus:

- (id) buildConnection
{
    // some more code and then:
    return [NSURLConnection …];
}

- (void) startNetworkSync
{
    id connection = [self buildConnection];
    //…
}

In dem Unit-Test würde Ich mag an der Vernetzung, um loszuwerden, das heißt. die NSURLConnection Aufgabe durch ein mock ersetzen. Wie mache ich das?

Ich habe versucht, eine partielle Mock des NetworkManager zu schaffen, die die buildConnection Methode durch einen Stub ersetzen würde. Das Problem ist, dass teilweise Mocks als getan von OCMock nur Stub-Nachrichten von der Außenwelt -. buildConnection vom startNetworkSync Senden der ursprünglichen Methode aufruft, nicht die Stub

Ich habe auch versucht, Affen-Patchen die NetworkManager Klasse durch eine Kategorie. Dies funktioniert, kann ich leicht die buildConnection Methode von anderen Code überschreiben und die reale NSURLConnection mit einem Stummel ersetzen. Das Problem ist, dass ich keine einfache Art und Weise fand ich die gekürzte Verbindung im Test bekommen konnte -. Die Verbindung ist ein privater Teil der NetworkManager

Dann könnte ich die NetworkManager Unterklasse, die buildConnection Methode außer Kraft setzen und eine Instanzvariable und einen Accessor für die erstellte Verbindung hinzufügen. Dies scheint eine Menge Code, though.

Wie würden Sie dieses Problem lösen? Ich bin auf der Suche nach einer Lösung, die NetworkManager Klasse Design sauber hält und nicht viel Magie noch viel Code im Test erforderlich ist.

War es hilfreich?

Lösung

Dies ist die Art von Dingen, Dependency Injection ist so konzipiert, zu lösen; wenn Sie startNetworkSyncWithConnection:(NSURLConnection*) verwenden stattdessen können Sie einfach die Methode mit einer Mock-Verbindung testen. Wenn Sie möchten, dass das API für Ihre Kunden nicht ändern könnten Sie sogar startNetworkSync als Wrapper halten, die nichts tun, sondern dass die neue Methode mit [self buildConnection] als Argument nennen.

Andere Tipps

I modifizierte OCMock zu echten Teil Mocks zu unterstützen, finden Sie die Repo auf GitHub rel="nofollow.

Eine andere Lösung, die ich vor kurzem verwendet haben, ist völlig abstrakt die Netzwerkschnittstelle. Wenn die Klasse einige Daten aus dem Netzwerk benötigt, es interagiert wahrscheinlich mit einem Server-Dienst, explictly als Protokoll modelliert werden kann:

@protocol SomeNetworkService
- (NSArray*) allAvailableFoos;
- (void) insertNewFoo: (Foo*) foo;
@end

Und dann werden Sie eine echte HTTP-Implementierung und eine Prüfung ein. Das bedeutet mehr Arbeit, aber auch viel besser Testbarkeit. Die Tests sind weniger spröde und viel bequemer, da die Testnetzwerkschicht tun, was Sie benötigen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top