如何使用OCMock初始化带有存根值的对象

时间:2011-09-14 09:13:38

标签: objective-c unit-testing ocmock

我是否存在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?

1 个答案:

答案 0 :(得分:12)

如果使用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");
}