2010-04-29 2 views
30

An meinem Tagesjob wurde ich mit Mockito's never() verification verwöhnt, was bestätigen kann, dass eine Scheinmethode nie aufgerufen wird.Wie kann ich mit OCMock überprüfen, dass eine Methode nie aufgerufen wird?

Gibt es eine Möglichkeit, dasselbe mit Objective-C und OCMock zu erreichen? Ich habe den Code unten verwendet, der funktioniert, aber es fühlt sich an wie ein Hack. Ich hoffe, dass es eine bessere Art und Weise ...

- (void)testSomeMethodIsNeverCalled { 
    id mock = [OCMockObject mockForClass:[MyObject class]]; 
    [[[mock stub] andCall:@selector(fail) onObject:self] forbiddenMethod]; 

    // more test things here, which hopefully 
    // never call [mock forbiddenMethod]... 
} 

- (void)fail { 
    STFail(@"This method is forbidden!"); 
} 

Antwort

59

Seit R69 von OCMock ist es möglich, eine Methode aufrufen http://svn.mulle-kybernetik.com/OCMock/trunk/Source/Changes.txt

Nizza Mocks ablehnen/Fehler schnell Wenn ein Methode auf einem Mock-Objekt aufgerufen wird, dass wurde nicht mit entweder oder Stub eingerichtet das Mock-Objekt wird eine Ausnahme auslösen. Diese Fail-Fast-Modus kann sein ausgeschaltet, indem ein „nice“ Mock:

id mock = [OCMockObject niceMockForClass:[SomeClass class]] 

Während schön spottet einfach alle unerwarteten Methoden ignorieren es möglich ist, spezifische Methoden zu umgehen:

[[mock reject] someMethod] 

Beachten Sie, dass im Fehlermodus die Ausnahme ignoriert wird und erneut durchlaufen wird, wenn Verify aufgerufen wird. Diese ermöglicht es, sicherzustellen, dass unerwünschte Aufrufe von Benachrichtigungen usw. erkannt werden können.

Zitat von: http://www.mulle-kybernetik.com/software/OCMock/#features

18

Soweit ich weiß OCMock automatisch fehlschlagen, wenn Sie überprüfen und Methoden aufrufen, die nicht genannt aufgezeichnet wurden, wurden. Ein Spott, der sich nicht beschweren würde, wenn unerwartete Methoden aufgerufen würden, wird als "schöner Spott" bezeichnet.

- (void)testSomeMethodIsNeverCalled { 
    id mock = [OCMockObject mockForClass:[MyObject class]]; 

    [mock forbiddenMethod]; 
    [mock verify]; //should fail 
} 
+0

die völlig funktioniert! Ich habe nicht erwartet, dass es so einfach ist. Willst du den Advokaten des Teufels spielen, denkst du, das verbirgt die Absicht des Tests? –

+0

@Justin: Nun, es erfordert, dass der Leser über OCMocks Verhalten in diesem Fall Bescheid weiß, was nicht allzu offensichtlich ist. Ein Kommentar direkt neben dem Scheinprüfungsaufruf sollte ausreichen, um klarzustellen, was passieren soll. Wie: '// Verify sollte fehlschlagen, weil wir eine unerwartete Methode für den Mock aufgerufen haben. –

0

Man könnte auch so etwas wie diese versuchen, a la JavaScript:

- (void)aMethod { 
    __block BOOL b = NO; 

    id mock = [OCMockObject mockForClass:[UIView class]]; 
    [[[mock stub] andDo:^(NSInvocation *i) { b = YES; }] resignFirstResponder]; 
    [mock resignFirstResponder]; 

    NSLog(@"And b is: %i", b); // This reads "And b is: 1" on the console 
} 

Ich bin nicht sicher, ob es irgendwelche Lecks mit diesem Code zugeordnet sind. Ich habe die Idee von der Lektüre dieser Seite: http://thirdcog.eu/pwcblocks/

3

können Sie auch eine Methode, um sicherzustellen, notwendig erachtet es nie auf einem Objekt aufgerufen wird, sind Sie teilweise spöttisch.

habe ich ein Makro dafür:

#define andDoFail andDo:^(NSInvocation *invocation) { STFail(@"Should not have called this method!"); } 

ich es wie folgt verwendet werden:

[[[_myPartialMock stub] andDoFail] unexpectedMethod]; 
+0

Wenn Sie modernen OCMock verwenden, empfehle ich' reject' wie in anderen Antworten angegeben. –

6

ab Version 3.3 OCMock hat OCMReject Makro.

id mock = OCMClassMock([MyObject class]); 
    OCMReject([mock forbiddenMethod]); 

    // exception will raise 
    [mock forbiddenMethod]; 
0

Um die Methode nicht aufgerufen stellen Sie sicher, ich denke, wir haben vor dem gerufenen testMethod eine Assertion zu tun.So sicher OCMReject setzen, bevor Sie das Testverfahren laufen, welche Methode hören wird ausgelöst, wenn läuft testMethod:

OCMReject([mock someMethod]); 
[mock testMethod]; 
+2

Während dieses Code-Snippet das Problem lösen kann, erklärt es nicht, warum oder wie es die Frage beantwortet. Bitte [fügen Sie eine Erklärung für Ihren Code hinzu] (// meta.stackexchange.com/q/114762/269535), da dies wirklich zur Verbesserung der Qualität Ihres Posts beiträgt. Denken Sie daran, dass Sie die Frage für Leser in der Zukunft beantworten, und diese Leute könnten die Gründe für Ihren Codevorschlag nicht kennen. ** Flaggers/Reviewer: ** [Für Code-only-Antworten wie diesen, downvote, nicht löschen!] (// meta.stackoverflow.com/a/260413/2747593) – Patrick

+0

@Patrick Erklärung hinzugefügt –

Verwandte Themen