OCMock:存根 @dynamic 属性
Posted
技术标签:
【中文标题】OCMock:存根 @dynamic 属性【英文标题】:OCMock: stub a @dynamic property 【发布时间】:2013-06-19 11:34:31 【问题描述】:我正在尝试将单元测试添加到现有的 ios 应用程序中,其中使用 OCMock
。
在这个应用程序中,我们有一堆 CoreData 实体和生成的类。这些类显然包含@dynamic
属性。
我尝试按如下方式对这些属性之一进行存根:
self.event = [OCMockObject mockForClass:[ACEvent class]];
[[[self.event stub] andReturn:@"e46e1555-d866-4160-9b42-36d0fb9c29cd"] eventGUID];
关键是,它不起作用。显然是因为 @dynamic
属性默认没有实现,在这种情况下依赖 CoreData 来提供它。我最终得到一个 NSError:
-[NSProxy doesNotRecognizeSelector:eventGUID] called!
我已经看到其他问题通过将 CoreData 实体抽象为协议 (OCMock with Core Data dynamic properties problem) 来解决。但由于这是一个现有的代码库,我没有这个选项,因为我负担不起重构所有内容。
谁能提供另一种解决方案?
编辑: 作为旁注,我刚刚找到了一个解决方案,但我担心它不能在所有情况下都有效。 我所做的是在测试目标中为这些方法提供了一个示例的空实现。它可以工作,但我担心它会破坏其他依赖 CoreData 工作的测试。对此有何见解?
【问题讨论】:
在类别中使用空方法应该可以。 OCMock 需要实现的原因是必须弄清楚方法签名是什么。一旦它知道存根应该工作。如果 OCMock 在模拟类中找不到方法,也许我们可以添加一些东西,让 OCMock 假定一个没有参数的方法和一个 id 返回类型。不过,这似乎有点脆弱。 【参考方案1】:使用 OCMock,我总是为每个托管对象创建一个协议,然后为这些协议创建模拟,但正如你所说,你不能这样做,所以我建议创建一个与你在代码中使用的相同属性的假类你想测试(对于每个NSManagedObject
),然后在传递那些假对象时只使用强制转换(你可以使用 OCMock 并存根你想要的方法,或者只是创建一个假类的对象并设置你想要的属性) .
【讨论】:
【参考方案2】:上面的答案让我不满意,因为我不喜欢为此创建协议。所以我发现有一种更简单的方法可以做到这一点。而不是
[[[self.event stub] andReturn:@"e46e1555-d866-4160-9b42-36d0fb9c29cd"] eventGUID];
随便写
[[[self.event stub] andReturn:@"e46e1555-d866-4160-9b42-36d0fb9c29cd"] valueForKey:@"eventGUID"];
【讨论】:
刚刚尝试使用最新版本的 OCMock。它没有用。看来核心数据不使用 valueForKey:。 :-(以上是关于OCMock:存根 @dynamic 属性的主要内容,如果未能解决你的问题,请参考以下文章