objective-c - 调用 + [NSBundle bundleForClass :] on a partially mocked object is returning a different result than the unmocked object?

标签 objective-c ocmock

我正在使用 XCTest 和 OCMock 2.2.1 进行单元测试。我有一个类,它使用以下方法获取包标识符:

NSString *bundleIdentifier = [[NSBundle bundleForClass:[self class]] bundleIdentifier];

在运行应用程序或此类的单元测试时,这将按预期工作。

在对其他类进行测试时,我部分地模拟了该对象,但仍然需要获取要运行的包标识符的方法。

我看到的是在将对象实例传递给 + [OCMockObjectpartialMockForObject:] 之前看起来正确:

(lldb) po myObject
<MyObject: 0x1006ec480>
(lldb) po [NSBundle bundleForClass:[myObject class]]
NSBundle </Users/paynerc/Library/Developer/Xcode/DerivedData/xxxx/Build/Products/Debug/MyTests Tests.xctest> (loaded)
(lldb) po [[NSBundle bundleForClass:[myObject class]] bundleIdentifier]
com.paynerc.MyBundle

但是,在我将 myObject 传递到 [OCMockObjectpartialMockForObject:myObject] 后,情况发生了变化:

(lldb) po myObject
<MyObject-0x1006ec480-401894396.880136: 0x1006ec480>
(lldb) po [NSBundle bundleForClass:[myObject class]]
NSBundle </Applications/Xcode.app/Contents/Developer/usr/bin> (loaded)
(lldb) po [[NSBundle bundleForClass:[myObject class]] bundleIdentifier]
nil

对象被修改并包含部分模拟魔法这一事实是有道理的。似乎没有意义的是为什么对 bundleForClass 的调用改变了它返回的内容。

除了模拟 MyObject 内部的调用之外,我还能做些什么来确保 bundleForClass 继续返回原始值吗?令人担忧的是,任何其他需要在另一个单元测试中部分模拟 MyObject 的人都需要记住提供 bundleForClass 的 stub 实现。

我目前的解决方案是请求包标识符并检查结果。如果它为零,我将调用 [NSBundle allBundles] 并迭代它们,直到找到一个具有非零的bundleIdentifier。虽然目前...有效...它 A) 不是很健壮 B) 非常暴力,C) 修改应用程序代码以支持单元测试。

还有其他人遇到过这个问题并提出更好的解决方案吗?

最佳答案

运行时运行正常。模拟对象是 NSProxy 的子类,因此是对象的 isa 之间的运行时绑定(bind)。并且该包被有效地破坏(特别是,isa 指向 Class,然后通过 dyld API 查找它以确定从中加载的 mach-o 镜像,并且 用于查找 bundle )。

OCMockObject 上可能有 API代理(或子类 OCPartialMockObject ),允许您检索原始类。当然,您必须使用它,这意味着您将通过仅应在测试中使用的模拟调用来污染您的代码。

或者,在您的包/框架/任何返回该类包的类中实现一个类方法。这不应该被 mock 。

关于objective-c - 调用 + [NSBundle bundleForClass :] on a partially mocked object is returning a different result than the unmocked object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19030194/

相关文章:

ios - 在 'ViewController' 类型的对象上找不到属性引用?

ios - 从 View Controller 上的方法内部测试/模拟称为类方法的 UIAlertView

objective-c - 我如何对 Objective-C 中方法内部的对象进行单元测试?

ios - OCMock - 验证方法调用的顺序。还有别的办法吗?

ios - 没有越狱检测

ios - CAGradientLayer 没有从 View 中删除自己

ios - 如何检测 UIButton 背景图片的变化?

ios - XmmpFramework + Openfire : manage offline messages

ios - 用 Swift 模拟

iphone - OCMock 测试失败 - 未调用预期的方法