OCMock无法识别的模拟对象选择器

时间:2013-12-05 01:12:36

标签: ios objective-c core-data ocmock

我有一个似乎与OCMockObject PartialMock有关的错误。 当模拟一个对象并对一个方法进行存根时,我得到了这个无法识别的选择器错误,我很确定这是一个订单或转换问题。 这是我的测试

STV_StreamServer *server = [NSEntityDescription insertNewObjectForEntityForName:@"STV_StreamServer"inManagedObjectContext:context];
id mockServer = [OCMockObject partialMockForObject:server];
[[[mockServer stub] andReturnValue:@YES] localURLPresent];
[[[mockServer stub] andReturnValue:@NO] remoteURLPresent];

id mockSUT = [OCMockObject partialMockForObject:sut];


[[[mockSUT stub] andReturnValue:@YES] canLiveStream:nil];

sut.streamServer = mockServer;

NSError *err = [mockSUT checkStreamingPlayabilityForUser:[self getUser:NO]];

XCTAssertNil(err, @"An error occured when basic user tried local playback");

sut是一个STV_MediaServer。我得到的错误是[STV_MediaServer-0xb39aba0-407898154.181220 setStreamServer:]: unrecognized selector sent to instance 0xb39aba0。所以首先我看到对象类型似乎是错误的,因为它现在包含看起来像内存位置的内容。当我嘲笑我的sut时会发生这种情况。我确定这是订单问题。谷歌搜索了几个小时。

2 个答案:

答案 0 :(得分:0)

我没有重现您的问题,但我认为不可能在托管对象中存储属性(使用@dynamic声明的CoreData)。

对于你展示的这种情况,你可以简单地将属性设置为你想要的值 - 这里不需要存根。

答案 1 :(得分:0)

您收到此错误是因为您在mockSUT上调用该方法。由于CoreData生成属性访问器的方式,OCMock无法将其实现复制到部分模拟,因此ObjC运行时无法找到它们。

当checkStreamingPlayabilityForUser最终调用self.streamServer时,self实际上是mockSUT,并且无法找到方法'streamServer'。

如果您只是按照特定测试所需的方式配置托管对象,那么这将正常工作。

FWIW你永远不应该尝试模拟NSManagedObject的实例,执行这些类型的测试的首选方法是在单元测试中创建适合您所需配置的测试对象。<​​/ p>


核心数据的数据驱动测试:

如果您创建可以为您管理CoreData位的SenTestCase或XCTestCase的子类,将会有所帮助。此测试用例子类应该为您的测试提供NSManagedObjectContext的实例。

实际测试可能如下所示:

@implementation PeopleViewControllerTest
  - (void)testSomething {
    NSMutableArray *people = [NSMutableArray new];
    [self.managedObjectContext performBlockAndWait:^{
      for (int i=0; i < 100; i++) {
        Person *p = [NSEntityDescription insertNewObjectForEntityForName:@"Person"
                                                  inManagedObjectContext:self.managedObjectContext];
        p.firstName = [NSString stringWithFormat:@"First%d", i];
        [people addObject:p];
      }
    }];
    //return the people
    PeopleViewController *pvc = ...;
    id mockPVC = [OCMockObject partialMockForObject:pvc];
    [[[mockPVC stub] andReturn:people] fetchedPeople];

    //make sure the view controller behaves properly with these 100 people
  }
@end

因此,我们不是创建100个NSManagedObject的模拟实例,而是创建100个实际对象。

我们不是试图测试CoreData,只是我们构建在一些NSManagedObjects之上的逻辑。因此,创建NSManagedObject的具体实例很好,但是应该将它们配置为运用应用程序的逻辑。

即。如果您想查看电子邮件地址验证,可能会:

p.emailAddress = @“notvalid”;

//稍后使用一些模拟对象    [[[partialMock expect] andReturn:p] person];