Как инициализировать объект с заглушенными значениями с помощью OCMock - PullRequest
4 голосов
/ 14 сентября 2011

Как мне заглушить метод, используемый в методе init?

Связанные методы в моем классе:

- (id)init
{
    self = [super init];
    if (self) {
        if (self.adConfigurationType == AdConfigurationTypeDouble) {
             [self configureForDoubleConfiguration];
        }
        else {
            [self configureForSingleConfiguration];
        }
    }
    return self;
}

- (AdConfigurationType)adConfigurationType
{
    if (adConfigurationType == NSNotFound) {
        if ((random()%2)==1) {
            adConfigurationType = AdConfigurationTypeSingle;
        }
        else {
            adConfigurationType = AdConfigurationTypeDouble;
        }
    }
    return adConfigurationType;
}

Мой тест:

- (void)testDoubleConfigurationLayout
{
    id mockController = [OCMockObject mockForClass:[AdViewController class]];
    AdConfigurationType type = AdConfigurationTypeDouble;
    [[[mockController stub] andReturnValue:OCMOCK_VALUE(type)] adConfigurationType];

    id controller = [mockController init];

    STAssertNotNil([controller smallAdRight], @"Expected a value here");
    STAssertNotNil([controller smallAdRight], @"Expected a value here");
    STAssertNil([controller largeAd], @"Expected nil here");
}

Мойрезультат:

Завершение работы приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «OCMockObject [AdViewController]: вызван непредвиденный метод: smallAdRight»

Так, как я получу доступ к AdViewController в OCMockObject?

1 Ответ

12 голосов
/ 14 сентября 2011

Если вы используете метод mockForClass:, вам нужно будет предоставить заглушенные реализации для каждого метода, вызываемого в проверяемом классе.включив в него ваш вызов с помощью [controller smallAdRight] в вашем первом тесте.

Вместо этого вы можете использовать метод niceMockForClass:, который будет просто игнорировать любые сообщения, которые не являются поддельными.создать экземпляр вашего AdViewController, а затем создать для него частичный макет, используя метод partialMockForObject:.Таким образом, внутренняя часть класса контроллера будет выполнять основную часть работы.

Хотя бы ... Вы пытаетесь протестировать AdViewController или класс, который его использует?Похоже, вы пытаетесь смоделировать весь класс, а затем проверить, все ли он ведет себя нормально.Если вы хотите проверить, что AdViewController ведет себя так, как ожидалось, при вводе определенных значений, то, скорее всего, лучшим вариантом будет partialMockForObject: метод:

- (void)testDoubleConfigurationLayout {     
  AdViewController *controller = [AdViewController alloc];
  id mock = [OCMockObject partialMockForObject:controller];
  AdConfigurationType type = AdConfigurationTypeDouble;
  [[[mock stub] andReturnValue:OCMOCK_VALUE(type)] adConfigurationType];

  // You'll want to call init after the object have been stubbed
  [controller init]

  STAssertNotNil([controller smallAdRight], @"Expected a value here");
  STAssertNotNil([controller smallAdRight], @"Expected a value here");
  STAssertNil([controller largeAd], @"Expected nil here");
}
...