5

我如何存根 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”

那么我将如何访问 OCMockObject 中的 AdViewController 呢?

4

1 回答 1

13

如果您使用该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");
}
于 2011-09-14T12:17:59.577 回答