2013-11-30 4 views
5

Я пытаюсь иметь дело с OCMock. Я создал простой класс MyClass.Как начать с OCMock и проверить, был ли вызван метод

@interface MyClass : NSObject 
- (NSString *)simpleMethod; 
@end 

@implementation MyClass 

- (NSString *)simpleMethod { 
    [self method]; 
    return @"simple"; 
} 

- (void)method { 
    NSLog(@"ABC"); 
} 

@end 

То, что я хочу, чтобы проверить, является ли метод method был вызван, когда simpleMethod был вызван. Теперь у меня есть следующий код, но он не работает:

- (void)testMethodInvoked 
{ 
    id mock = [OCMockObject mockForClass:[MyClass class]]; 
    [[mock stub] simpleMethod]; 

    SEL selector = NSSelectorFromString(@"method"); 
    [[mock expect] methodForSelector:selector]; 
    [mock verify]; 
} 

Как проверить этот случай? Я думаю, что это довольно легко сделать, но я понятия не имею, как решить эту проблему.

Как создать метод mock и call simpleMethod, который вызывает метод method?

Текущий журнал:

<unknown>:0: error: -[OCMockTestTests testOne] : OCMockObject[MyClass]: expected method was not invoked: methodForSelector:@selector(method) 

ответ

12

Вы никогда не создать объект класса, который вы хотите проверить. Кроме того, вы должны expect первым, а затем вызвать метод:

- (void)testMethodInvoked 
{ 
    // first create an object that you want to test: 
    MyClass *object = [[MyClass alloc] init]; 
    // create a partial mock for that object 
    id mock = [OCMockObject partialMockForObject:object]; 
    // tell the mock object what you expect 
    [[mock expect] method]; 
    // call the actual method on the mock object 
    [mock simpleMethod]; 
    // and finally verify 
    [mock verify]; 
} 
+0

Спасибо но проблема в том, что 'method' является частным методом, не видны за пределами класса' MyClass' –

+3

Не звучит как подходящее условие для единичного теста, а затем @TomaszSzulc. Модульные тесты для интерфейсов - внешнее поведение - не реализация. –

+0

@JoshCaswell Спасибо за совет. –

4

Я иногда найти его полезным для тестирования «частные» методы/реализации - возможно, не назвать это тестовый модуль, если это нарушает какой-то ортодоксия - но для сложной реализации я могу проверить поведение на более узком уровне, чем через внешний интерфейс.

В любом случае, я буду выставлять методы расширения класса, создав категорию в тестовом классе:

@interface MyClass (ExposeForTest) 
- (void)method; 
@end 

- (void)testMyClass 
{ 
    id mock = [OCMockObject mockForClass:MyClass.class]; 
    [[mock expect] method]; 
    [mock simpleMethod]; 
} 
+0

Технически это расширение класса, а не категория. Но вы правы, это самый чистый способ разоблачения частных методов в тестовых случаях. –

+0

@ChristopherPickslay Дискуссионный, да? Расширения класса используют синтаксис '@interface MyClass()' - также называемые анонимными категориями. Но, поскольку мы не обеспечиваем реализацию, как мы это делаем с названными категориями, я могу видеть, откуда вы. https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html –

Смежные вопросы