我目前正在爲iPad應用程序編寫圖像操作測試。我的單元測試目標中有一個資源文件夾,裏面有一張照片,但是當我嘗試使用[UIImage imageNamed:@「photo1.jpg」]訪問它時,沒有圖像被返回。如果我在主資源文件夾中將文件名更改爲一個,則圖像將返回。訪問OCUnit測試目標內的UIImage
有沒有辦法訪問單元測試目標中的Resources文件夾?
我目前正在爲iPad應用程序編寫圖像操作測試。我的單元測試目標中有一個資源文件夾,裏面有一張照片,但是當我嘗試使用[UIImage imageNamed:@「photo1.jpg」]訪問它時,沒有圖像被返回。如果我在主資源文件夾中將文件名更改爲一個,則圖像將返回。訪問OCUnit測試目標內的UIImage
有沒有辦法訪問單元測試目標中的Resources文件夾?
找到這個問題的答案,看起來你無法使用[UIImage的imageNamed:],您可以訪問這樣的形象:
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *imagePath = [bundle pathForResource:@"photo1" ofType:@"jpg"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
您可以使用以下類別(但僅添加測試目標!)。在測試目標自動方法工作:它將使UIImage的imageNamed
.h文件中
/**
* UIImage imageNamed: method does not work in unit test
* This category provides workaround that works just like imageNamed method from UIImage class.
* Works only for png files. If you need other extension, use imageNamed:extension: method.
* NOTE: Do not load this category or use methods defined in it in targets other than unit tests
* as it will replace original imageNamed: method from UIImage class!
*/
@interface UIImage (ImageNamedForTests)
/**
* Returns image with the specified name and extension.
* @param imageName Name of the image file. Should not contain extension.
* NOTE: You do not have to specify '@2x' in the filename for retina files - it is done automatically.
* @param extension Extension for the image file. Should not contain dot.
* @return UIImage instance or nil if the image with specified name and extension can not be found.
*/
+ (UIImage *)imageNamed:(NSString *)imageName extension:(NSString *)extension;
@end
做了一個方便的類別爲這個.m文件
#import "UIImage+ImageNamedForTests.h"
#import <objc/runtime.h>
@implementation UIImage (ImageNamedForTests)
+ (void)load {
[self swizzleClassMethod];
}
+ (void)swizzleClassMethod {
SEL originalSelector = @selector(imageNamed:);
SEL newSelector = @selector(swizzled_imageNamed:);
Method origMethod = class_getClassMethod([UIImage class], originalSelector);
Method newMethod = class_getClassMethod([UIImage class], newSelector);
Class class = object_getClass([UIImage class]);
if (class_addMethod(class, originalSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
class_replaceMethod(class, newSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
} else {
method_exchangeImplementations(origMethod, newMethod);
}
}
+ (UIImage *)swizzled_imageNamed:(NSString *)imageName {
return [self imageNamed:imageName extension:@"png"];
}
+ (UIImage *)imageNamed:(NSString *)imageName extension:(NSString *)extension {
NSBundle *bundle = [NSBundle bundleForClass:[SomeClassFromUnitTestTarget class]];//Any class from test bundle can be used. NOTE: Do not use UIImage, as it is from different bundle
NSString *imagePath = [bundle pathForResource:imageName ofType:extension];
return [UIImage imageWithContentsOfFile:imagePath];
}
。
image = [UIImage testImageNamed:@"image.png"];
是這樣:
@interface BundleLocator : NSObject
@end
@interface UIImage (Test)
+(UIImage*)testImageNamed:(NSString*) imageName;
@end
@implementation BundleLocator
@end
@implementation UIImage (Test)
+(UIImage*)testImageNamed:(NSString*) imageName
{
NSBundle *bundle = [NSBundle bundleForClass:[BundleLocator class]];
NSString *imagePath = [bundle pathForResource:imageName.stringByDeletingPathExtension ofType:imageName.pathExtension];
return [UIImage imageWithContentsOfFile:imagePath];
}
@end
由於iOS 8的我們有:上UIImage
-imageNamed:inBundle:compatibleWithTraitCollection:
方法在夫特:
let bundle = NSBundle(forClass: self.dynamicType)
let image:UIImage? = UIImage(named: "imageFileName",
inBundle:bundle,
compatibleWithTraitCollection:nil)
在Objective-C
NSBundle* bundle = [NSBundle bundleForClass:[self class]];
UIImage* image = [UIImage imageNamed:@"imageFileName.extension"
inBundle:bundle
compatibleWithTraitCollection:nil];
這個答案應該在頂部。我已經爲UIImage創建了一個新的初始化工具來完成這個工作。我現在感覺有些笨拙。 https://gist.github.com/Psidium/6d15525d4fba7b191290 – 2015-04-23 17:12:48
謝謝,這解決了我的問題。 – 2015-05-06 22:35:48