OCMock 没有传播到实现代码中 - iOS Xcode CocaPod

Posted

技术标签:

【中文标题】OCMock 没有传播到实现代码中 - iOS Xcode CocaPod【英文标题】:OCMock not propagating into implementation code - iOS Xcode CocaPod 【发布时间】:2014-09-16 18:39:04 【问题描述】:

在测试期间,我无法让使用 OCMock 制作的模拟传播到我的实现代码中。

我已经使用 CocoaPods 将 OCMock 安装到我的 ios 项目中,并尝试了多个类模拟和部分对象模拟实现。

例如:

MYCLASS 的实现代码

+ (int) returnsFive  
     return 5;

MYCONTROLLER的实现代码

#import "MyClass.h"

- (void) viewDiDLoad  
     self.number = [MyClass returnsFive]; 

测试代码

id myClassMock = [[MyClass alloc] init];
OCMStub([myClassMock returnsFive]).andReturn(7);

NSLog(@"%@", [MyClass returnsFive]); // -- ((this prints out 7))

[MyController layoutIfNeeded]; // -- ((runs viewDidLoad))

XCTAssertEqual(MyController.number, 7, @"the number property on MyController should be set to 7 after mock"); 

// -- ((this fails, MyController.number equals 5 and not 7 as stubbed out))  

结论和问题

类模拟在测试中运行时有效,但是在实现代码中运行时,模拟不会继续。实际的类(即 MyClass)被运行而不是模拟。

我们已经尝试过使用不同的模拟变体(即对对象进行部分模拟以及在实例方法上使用模拟而不是类方法)。在模拟没有传播到实现代码中的情况下,所有这些都产生了完全相同的结果。

1.) 这可能吗? (应该是这样)

2.) 是否缺少一些设置步骤? (我们使用 CocoaPods 安装了 OCMock,并使用 #import 将框架导入到我们的 testClass 中)

3.) 关于如何解决我们的困境的任何想法???

【问题讨论】:

你确定viewDiDLoad 会被调用吗?我问是因为第二个 D 是大写 D,这不太可能是正确的。当您在layoutIfNeeded 调用之后直接添加[MyController viewDiDLoad] 调用时会发生什么?顺便说一句,我假设MyController 是变量名,而不是类名。使用以大写字母开头的变量名是不寻常的(并且令人困惑)。 【参考方案1】:

您可以在此处查看功能齐全的示例:

https://github.com/uShip/ocmock-singletons-example

查看名为“testToggleOnRegistersForPushNotifications_On_OCMock_NoDI”的测试。它为 UIApplication 创建一个模拟,并验证模拟实例的某些方法是否被调用。

【讨论】:

以上是关于OCMock 没有传播到实现代码中 - iOS Xcode CocaPod的主要内容,如果未能解决你的问题,请参考以下文章

无法识别 OCMock 的头文件

如何使用 OCMock 3 在单元测试中检查函数的返回值

OCMock:存根 @dynamic 属性

使用 OCMock 静态库进行 iOS 单元测试(-ObjC 标志问题)

IOS单元测试,OCMock

LSTM 反向传播梯度检查的问题