Iphone 在iOS4和Xcode 4/SDK4.3中使用OCMock 1.77进行单元和应用程序测试

Iphone 在iOS4和Xcode 4/SDK4.3中使用OCMock 1.77进行单元和应用程序测试,iphone,objective-c,xcode,ocmock,Iphone,Objective C,Xcode,Ocmock,我正在尝试使用OCMock 1.77对iOS4和Xcode 4/SDK4.3进行单元和应用程序测试。我已经按照说明使用OCMock作为静态库进行了操作,可在此处找到:。单元和应用程序测试在没有OCMock的情况下运行良好 当我添加OCMock并尝试为模拟器运行OCMock的测试套件(单元测试)时,我的测试平台崩溃,代码为134。对于设备而言,试验台运行良好(应用测试)。如果我查看控制台,我会看到下面的消息——这表明我没有按照上面URL的说明添加-force_load linker标志。但是我有。

我正在尝试使用OCMock 1.77对iOS4和Xcode 4/SDK4.3进行单元和应用程序测试。我已经按照说明使用OCMock作为静态库进行了操作,可在此处找到:。单元和应用程序测试在没有OCMock的情况下运行良好

当我添加OCMock并尝试为模拟器运行OCMock的测试套件(单元测试)时,我的测试平台崩溃,代码为134。对于设备而言,试验台运行良好(应用测试)。如果我查看控制台,我会看到下面的消息——这表明我没有按照上面URL的说明添加-force_load linker标志。但是我有。。。有什么想法吗

我看了一下:这表明这种行为是一个bug——但我不确定这是否是相同的情况,因为我正在运行OCMock测试套件。如果它是一个bug,那么在单元测试中是否有使用mock的解决方案

蒂亚

=====

控制台输出:

3/30/11 1:02:32 AM  otest[38552]    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '** Expected method not present; the method getArgumentAtIndexAsObject: is not implemented by NSInvocation. If you see this exception it is likely that you are using the static library version of OCMock and your project is not configured correctly to load categories from static libraries. Did you forget to add the -force_load linker flag?'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x004a05a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x002cf313 objc_exception_throw + 44
    2   CoreFoundation                      0x00458ef8 +[NSException raise:format:arguments:] + 136
    3   CoreFoundation                      0x00458e6a +[NSException raise:format:] + 58
    4   LogicTests                          0x00f89de4 +[OCMockObject initialize] + 115
    5   libobjc.A.dylib                     0x002cfd9b _class_initialize + 380
    6   libobjc.A.dylib                     0x002d773f prepareForMethodLookup + 73
    7   libobjc.A.dylib                     0x002ce069 lookUpMethod + 86
    8   libobjc.A.dylib                     0x002ce1d6 _class_lookupMethodAndLoadCache + 40
    9   libobjc.A.dylib                     0x002e10e3 objc_msgSend + 87
    10  SenTestingKit                       0x20108824 +[NSObject(SenTestRuntimeUtilities) senAllSubclasses] + 107
    11  SenTestingKit                       0x201074a7 +[SenTestSuite updateCache] + 39
    12  SenTestingKit                       0x20107443 +[SenTestSuite suiteForBundleCache] + 92
    13  SenTestingKit                       0x201073a4 +[SenTestSuite testSuiteForBundlePath:] + 108
    14  SenTestingKit                       0x2010606b +[SenTestProbe specifiedTestSuite] + 332
    15  SenTestingKit                       0x20106792 +[SenTestProbe runTests:] + 156
    16  otest                               0x000023c7 0x0 + 9159
    17  otest                               0x000025f2 0x0 + 9714
    18  otest                               0x0000209a 0x0 + 8346
    19  otest                               0x00002049 0x0 + 8265
)

我可以通过删除-force_load标志来重现这一点。检查以确保它设置在您的测试目标上,而不是主目标上,并且它指向静态库的正确位置。就我而言,那是

-force_load $(PROJECT_DIR)/Libraries/libOCMock.a
您链接的只是说,当mock的
verify
方法失败时,它会从NSInvocation上的category方法引发异常,这会导致otest崩溃。它仍然有效;该消息比断言失败更为神秘,断言失败将XCode标记为测试类中的错误。

  • 从下载OCMock******(撰写本文时为1.77)
  • 在OCMock/(或其他文件夹)中解包-->您将有两个文件夹“Release”和“Source”
  • 复制xCode项目文件夹中的“Release/Library”文件夹
  • 使用xcode将文件链接到项目中的所有“库”文件夹
    • 选择应用程序测试目标作为目标
  • 转到测试目标的“生成设置”
    • 在“搜索路径”下添加:+“标题搜索路径”-->插入OCMock标题(.h)的路径(类似$(PROJECT_DIR)/Library/headers) +“库搜索路径”-->插入OCMock库(.a)的路径(类似$(PROJECT_DIR)/Library/) 注意:作为路径,您还可以使用$(PROJECT\u DIR)或$(SRCROOT)/并选中递归复选框,以避免插入OCComplete路径
      • 在“链接”下添加:+“其他链接标志”-->-全部加载
现在一切都应该正常工作了。核实:

#import <OCMock/OCMock.h>
// simple test to ensure building, linking, 
// and running test case works in the project
- (void)testOCMockPass {
id mock = [OCMockObject mockForClass:NSString.class];
[[[mock stub] andReturn:@"mocktest"] lowercaseString];
NSString *returnValue = [mock lowercaseString];
STAssertEqualObjects(@"mocktest", returnValue, @"Should have returned the expected string.");
}

- (void)testOCMockFail {
id mock = [OCMockObject mockForClass:NSString.class];
[[[mock stub] andReturn:@"mocktest"] lowercaseString];
NSString *returnValue = [mock lowercaseString];
STAssertEqualObjects(@"thisIsTheWrongValueToCheck", returnValue, @"Should have returned the expected string."); 
}
#导入
//简单测试,确保建筑、连接、,
//并在项目中运行测试用例
-(void)testOCMockPass{
id mock=[OCMockObject mockForClass:NSString.class];
[[[mock stub]andReturn:@“mocktest”]小写];
NSString*returnValue=[mock lowercaseString];
STAssertEqualObjects(@“mocktest”,returnValue,@“应该已返回所需的字符串”);
}
-(void)testOCMockFail{
id mock=[OCMockObject mockForClass:NSString.class];
[[[mock stub]andReturn:@“mocktest”]小写];
NSString*returnValue=[mock lowercaseString];
STAssertEqualObjects(@“ThisisthewOngValueToCheck”,returnValue,@“应该已返回所需的字符串”);
}
非常感谢:

  • 拉尔夫·霍夫曼对他的耐心和先入为主的时间表示感谢


Enrico Bottani

测试目标上的标志设置正确。在我创建要运行的测试用例之前,单元测试目标就崩溃了——所以这不仅仅是一个神秘的断言失败。我很确定这个错误导致了这个问题:这个错误不是上面堆栈跟踪的原因。该缺陷与无法捕获异常有关——在OCMock的上下文中,这意味着验证失败会产生一个不太理想的错误,因为OCMock无法捕获失败并将其包装。堆栈跟踪显示GetArgumentIndexAsObject,一个由OCMock库在NSInvocation类别上定义的方法,不存在。这是因为没有从静态库加载类别。看见您确定-force_load后面有到静态库的正确路径吗?尝试将其替换为-all_load。如果这样做有效的话,加载后的路径很可能是错误的,或者你的链接器标志还有其他一些古怪的地方。我非常感谢你一直在那里帮助我chrispix。我现在已经尝试了很多不同的配置。当我使用当前项目的状态——运行非OCMock单元测试和OCMock应用程序测试时,使用以下标志设置:HEADER\u SEARCH\u PATHS=/usr/include/libxml2$(project\u DIR)/Libraries/Headers,LIBRARY\u SEARCH\u PATHS=$(继承的)$(srcrroot)/Libraries“$(继承的)$(project\u DIR)/Libraries”FraseFieldFrase-框架SENTest-KIT-FraseUIKIT-LXML2-Obj-FultLoad $(PrimeXDIR)/库/ LIBOCMOCK。