同时使用反应性可可、猕猴桃和椰子荚,得到"is not a tuple"例外



我正在尝试使用ReactiveCocoa和Kiwi进行测试,使用CocoaPods进行依赖性管理来建立一个新项目。

我为一个典型的登录屏幕设置了第一个测试,在用户输入用户名和密码之前,登录按钮不会启用。只是一些示例代码的简单版本:

- (void)viewDidLoad
{
    [super viewDidLoad];
    RAC(self.loginButton, enabled) = [RACSignal combineLatest:@[self.userNameField.rac_textSignal,
                                                            self.passwordField.rac_textSignal]
                                                       reduce:^(NSString *username, NSString *password) {
        return @(username.length > 0 && password.length > 0);
    }];
}

问题是,当我运行测试时,我会得到以下错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Value from stream <RACDynamicSignal: 0xe3735a0> name: +combineLatest: (
    "<RACDynamicSignal: 0xe368c50> name: <UITextField: 0xe3707a0> -rac_textSignal",
    "<RACDynamicSignal: 0xe372d80> name: <UITextField: 0xe36aef0> -rac_textSignal"
) is not a tuple: <RACTuple: 0xe377a40> (
    "",
    ""
)'

当然,它是一个RACTuple,所以这只是令人困惑。

我的研究发现了以下关于ReactiveCocoa的问题:

https://github.com/ReactiveCocoa/ReactiveCocoa/issues/901

那里的诊断是,ReactiveCocoa不知何故被联系了两次。在那里遇到问题的人抛弃了CocoaPods,解决了这个问题。这似乎不对。有人让它工作了吗?

为了完整起见,我的播客文件是:

platform :ios, '6.0'
pod 'ReactiveCocoa'
target :test do
  link_with 'PollVaultTests'
  pod 'Kiwi/XCTest'
end

好吧,我要回答我自己的问题了。

事实证明,当pod在Podfile中以"全局"级别列出时,CocoaPods会将它们包含在所有目标中。

本例的结果是,我的主要项目链接在CocoaPods中,我的测试目标也是如此。

当我的测试目标被注入到我的主项目中以运行测试时,你会得到两次ReactiveCocoa链接。因此,有两个名为RACTuple的类四处浮动,因此,当ReactiveCocoa代码内部检查以确保其参数是RACTuple时,它会检查该类的错误副本,并有效地得到假阴性结果。

解决方案是确保我在Podfile中的测试目标配置为仅在中链接测试吊舱,如下所示:

platform :ios, '6.0'
pod 'ReactiveCocoa'
target :test, :exclusive => true do
  link_with 'PollVaultTests'
  pod 'Kiwi/XCTest'
end

:exclusive => true部分是告诉Cocoapods在我的测试目标中只包含Kiwi测试框架的部分。问题解决了!

相关内容

最新更新