不能在Xcode 5.0中使用OCMock 2.1+存根类方法 [英] cannot stub class method with OCMock 2.1+ in Xcode 5.0

查看:97
本文介绍了不能在Xcode 5.0中使用OCMock 2.1+存根类方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道OCMock版本2.1+ 支持可以直接使用类方法.但是由于某种原因,它无法与我一起使用.为确保找出问题所在,我仅克隆了示例 OCMock项目(显然标记为2.2版) .1),只需将其添加到 testMasterViewControllerDeletesItemsFromTableView :

id detailViewMock = [OCMockObject mockForClass:[DetailViewController class]];
[[[detailViewMock stub] andReturn:@"hello"] helloWorld]; 

我在DetailViewController.h中添加了

:

+ (NSString *)helloWorld;

DetailViewController.m:

+ (NSString *)helloWorld {
    return @"hello world";
}

但是我继续收到错误消息:

*** -[NSProxy doesNotRecognize Selector:helloWorld] called!

要查看该问题的演示,请克隆回购以查看发生了什么.

解决方案

那应该可以正常工作.我刚刚在一个我的项目中尝试过,该项目在Xcode5上使用XCTest,并且该代码已通过.

我会:1)确保您使用的是最新版本的OCMock(目前为2.2.1;我认为较新版本中的类方法和Xcode5都有一些修复),以及2)确保您的DetailViewController类在运行时中正确链接(即正确目标的一部分).

在查看您的项目时,您的DetailViewController类是主应用程序的一部分.对于Xcode5,这似乎意味着该类的两个副本已编译并存在于运行时中,应用程序中的代码调用一个副本,而测试用例中的代码调用另一个副本.这曾经是一个链接器错误(重复的符号),但是无论好坏,链接器现在似乎默默地允许ObjC运行时中存在两个相同类(具有相同名称)的副本. OCMock使用动态查找来找到第一个(编译到应用程序中的一个),但是测试用例直接链接到第二个副本(编译到测试包中的一个).所以... OCMock实际上并没有嘲笑您认为是的类.

您可以通过在测试用例中验证[DetailViewController类]不等于NSClassFromString(@"DetailViewController")(第一个直接链接,第二个是动态链接)来看到这一点. >

要正确解决此问题,请在DetailViewController.m的目标成员身份"中,取消选中测试目标.这样,在运行时中只有一个类的副本,并且事情按您期望的那样工作.测试捆绑软件被加载到主应用程序中,因此所有主应用程序的类都应可用于捆绑软件,而不必直接将它们编译到捆绑软件中.类只能是两个目标之一的一部分,而不是两者(一直都是这种情况).

I know that OCMock version 2.1+ supports stubbing class methods out of the box. But for some reason it's not working with me. To make sure I isolated the problem, I simply cloned the example OCMock project (which is clearly marked as version 2.2.1) and simply added this inside testMasterViewControllerDeletesItemsFromTableView:

id detailViewMock = [OCMockObject mockForClass:[DetailViewController class]];
[[[detailViewMock stub] andReturn:@"hello"] helloWorld]; 

in DetailViewController.h I added:

+ (NSString *)helloWorld;

and DetailViewController.m:

+ (NSString *)helloWorld {
    return @"hello world";
}

But I keep on getting the error:

*** -[NSProxy doesNotRecognize Selector:helloWorld] called!

to see a demo of the problem please clone this repo to see what's going on.

解决方案

That should work just fine. I just tried in a project of mine which uses XCTest on Xcode5, and that code passed.

I would 1) make sure you are using the latest version of OCMock (which is 2.2.1 right now; I think there are some fixes for both class methods and Xcode5 in the newer versions), and 2) make sure your DetailViewController class is linked in the runtime (i.e. part of the correct target) correctly.

In looking at your project, your DetailViewController class is part of both the main application, and the test target. With Xcode5, it appears this means that two copies of the class get compiled and are present in the runtime, with code in the app calling one copy, and code in the test case calling the other. This used to be a linker error (duplicate symbols), but for better or worse, the linker now appears to silently allow two copies of the same class (with the same name) to exist in the ObjC runtime. OCMock, using dynamic lookup, finds the first one (the one compiled into the app), but the test case is directly linked to the second copy (the one compiled into the test bundle). So... OCMock is not actually mocking the class you think it is.

You can see this, just for grins, by verifying as part of the test case that [DetailViewController class] will not equal NSClassFromString(@"DetailViewController") (the first is directly linked, the second is dynamic).

To fix this properly, in the "Target Memberships" for DetailViewController.m, just uncheck the test target. This way there is only one copy of the class in the runtime, and things work like you'd expect. The test bundle gets loaded into the main application, so all of the main application's classes should be available to the bundle without having to directly compile them into the bundle. Classes should only be part of one of the two targets, not both (this has always been the case).

这篇关于不能在Xcode 5.0中使用OCMock 2.1+存根类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆