OCUnit和NSBundle

39

我按照《iPhone开发指南》创建了OCUnit测试。这是我想要测试的类:

// myClass.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface myClass : NSObject {
    UIImage *image;
}
@property (readonly) UIImage *image;
- (id)initWithIndex:(NSUInteger)aIndex;
@end


// myClass.m
#import "myClass.m"

@implementation myClass

@synthesize image;

- (id)init {
    return [self initWithIndex:0];
}

- (id)initWithIndex:(NSUInteger)aIndex {
    if ((self = [super init])) {
        NSString *name = [[NSString alloc] initWithFormat:@"image_%i", aIndex];
        NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"png"];
        image = [[UIImage alloc] initWithContentsOfFile:path];
        if (nil == image) {
            @throw [NSException exceptionWithName:@"imageNotFound"
                reason:[NSString stringWithFormat:@"Image (%@) with path \"%@\" for current index (%i) wasn't found.",
                    [name autorelease], path, aIndex]
                userInfo:nil];
        }
        [name release];
    }
    return self;
}

- (void)dealloc {
    [image release];
    [super dealloc];
}

@end

以下是我的单元测试(LogicTests目标):

// myLogic.m
#import <SenTestingKit/SenTestingKit.h>
#import <UIKit/UIKit.h>
#import "myClass.h"

@interface myLogic : SenTestCase {
}
- (void)testTemp;
@end

@implementation myLogic

- (void)testTemp {
    STAssertNoThrow([[myClass alloc] initWithIndex:0], "myClass initialization error");
}

@end

所有必要的框架, "myClass.m" 文件和图像已添加到目标。但是在构建过程中我遇到了一个错误:

[[myClass alloc] initWithIndex:0] 报错:当前索引(0)对应的图像(image_0)路径为“(null)”未找到。myClass 初始化错误。

这段初始化代码在应用程序本身(主目标)中运行良好,并且随后显示正确的图像。我还检查了我的项目文件夹(build/Debug-iphonesimulator/LogicTests.octest/) - 那里有 LogicTestsInfo.plist 和必要的图像文件之一(image_0.png)。

出了什么问题?


2
在kpower的解决方案基础上,我想出了以下Xcode:TEST vs DEBUG预处理器宏 - ma11hew28
1个回答

128

对于这个问题,我只找到了一种解决方案。

在构建单元测试时,主bundle的路径与我的项目bundle(创建的.app文件)不相同。而且,它也不等于LogicTests bundle(创建的LogicTests.octest文件)。

单元测试的主bundle类似于/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.3.sdk/Developer/usr/bin。这就是程序无法找到必要资源的原因。

最终的解决方案是获取直接的bundles:

NSString *path = [[NSBundle bundleForClass:[myClass class]] pathForResource:name ofType:@"png"];

取代

NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"png"];

24
谢谢您的回答。使用[self class]也是可行的,将该行代码保留为NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:name ofType:@"png"]; - Macarse
1
据我所知,当您开发标准的iPhone应用程序时,唯一的捆绑包用于存储所有源和资源。因此,理论上,任何“自定义”(由您自己创建)类都可以在此处使用。但我没有验证过这个想法。 - kpower
非常感谢,我已经寻找这个答案三天了。 - aryaxt
1
在苦苦挣扎了相当长一段时间后,这个答案简直是救星。虽然已经有将近6年的历史了,但对于像我这样想要对包含bundle的静态库进行单元测试的人来说,它仍然是一个很好的解决方案。 - John Rogers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接