2009-08-17 10 views
17

Próbuję mock metodę, która ma równowartość następujący podpis:Jak wyśmiewać metodę, która akceptuje uchwyt jako argument w OCMock?

- (NSDictionary *) uploadValues:(BOOL)doSomething error:(NSError **)error 

chcę go zwrócić małą słownika tak, że mój test może upewnić się, że kod używa słownika prawidłowo. jednak bez względu na to, co robię, OCMock zawsze zwraca zero z metody, niezależnie od tego, jak ją rozpracować. Błąd zaczyna się zera w kodzie I 'm testowania, a te są różne sposoby próbowałem stubbing go:

NSError * error = nil; 
[[[mock stub] andReturn:someDict] uploadValues:YES error:&error]; 

[[[mock stub] andReturn:someDict] uploadValues:YES error:nil]; 

[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg any]]; 

i żaden z nich nie działa. Czy OCMock obsługuje uchwyty w postaci skrótowych argumentów wiadomości, a jeśli tak, to w jaki sposób to zrobić?

Odpowiedz

-3

Niestety, również nie znalazłem dobrego rozwiązania. Najlepsze, co mogę powiedzieć, to spróbować jak najprościej wykorzystać NSError **, a następnie umieścić go w odizolowanej funkcji, którą można całkowicie wyśmiać w częściowej próbie.

Znajduję, że każdy kod, który używa czegoś innego niż wartość NSObject * (lub wyprowadzona) lub prymitywna (NSInteger, BOOL, itp.) Jest prawie niemożliwa do przetestowania przy użyciu OCMock.

+0

Tak, to ma sens. Dzięki za wgląd. – Kevlar

+3

Używanie i dostarczanie metod akceptujących NSError ** jest preferowanym mechanizmem obsługi błędów w Cocoa. Proponuję trzymać się tego paradygmatu i rzucić okiem na odpowiedź Andreasa Järlidena, aby sfałszować te metody. – rluba

+2

Zobacz odpowiedź Andreasa Järlidena poniżej. Twoja odpowiedź jest niepoprawna. – markshiz

43
[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg setTo:nil]]; 

lub

NSError* someError = ... 
[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg setTo:someError]]; 

Można również zrobić

[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg anyPointer]]; 

ale może to spowodować, że kod niepoprawnie uważają, że przeszedł z powrotem prawdziwe NSError.

+5

W najnowszych wersjach OCMocka można użyć '[OCMArg anyObjectRef]' zamiast '[OCMArg anyPointer]', aby uniknąć błędów pod kontrolą ARC, gdy mamy do czynienia ze wskaźnikami do wskaźników obiektów typu Objective-C (takich jak 'NSError ** '). –

3

Z ARC, twoja deklaracja metoda będzie prawdopodobnie wyglądać następująco:

- (NSDictionary *) uploadValues:(BOOL)doSomething error:(NSError *__autoreleasing *)error; 

Oto jak wyśmiewać te rodzaje metod:

BOOL mockDoSomething = YES; 

NSError __autoreleasing *error = nil; 

[[[mock stub] andReturn:someDict] uploadValues:OCMOCK_VALUE(mockDoSomething) error:&error]; 
+1

W szczególności, następujące wydaje się działać dobrze w oczekujemy: błędzie: ((NSError __autoreleasing **) [OCMArg anyPointer]) –

3
NSError *__autoreleasing *err = (NSError *__autoreleasing *) [OCMArg anyPointer]; 

[[[_mockReporter stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})] 
    yourMethodCall:err]; 
+0

To działało jak urok dla mnie. –

3

stworzyłem kategorię na OCMArg do pomoc w tej sytuacji.

OCMArg + Helpers.h:

@interface OCMArg (Helpers) 

+ (NSError *__autoreleasing *)anyError; 

@end 

OCMArg + Helpers.m:

@implementation OCMArg (Helpers) 

+ (NSError *__autoreleasing *)anyError { 
    return (NSError *__autoreleasing *)[OCMArg anyPointer]; 
} 

@end 

Wtedy, gdy mam param błędzie muszę drwić, użyj anyError, tak:

[[myMock stub] someMethodWithArg:anArg error:[OCMArg anyError]]; 
+1

Wygląda też na to, że najnowsza wersja OCMocka na GitHub ma coś podobnego w OCMarg, '+ (id __autoreleasing *) anyObjectRef'. –

Powiązane problemy