NSURL用XCTest在testing包中loggingpath
我正在尝试使用TDD和新的XCTest框架编写iOS应用程序。 我的一个方法从互联网上检索一个文件(给定一个NSURL对象)并将其存储在用户的文档中。 该方法的签名类似于:
- (void) fetchAndStoreImage:(NSURL *)imageUrl 我试图用这种方法编写testing,如果没有连接到互联网,它不会失败。 我的做法(从前面的问题中获得 )是使用NSURL调用本地文件系统中的映像的方法。
当创build一个unit testing启用的新项目时,Tests目录有一个名为“支持文件”的子目录。 我想这是我的testing图像应该去的地方。 我的问题是如何获得一个指向这个目录中的图像的NSURL对象,因为我不希望testing图像与应用程序捆绑在一起。 任何帮助表示赞赏。
实际上,运行UnitTest时的[NSBundle mainBundle] 不是你的应用程序的path,而是/ Developer / usr / bin,所以这是行不通的。
在unit testing中获取资源的方法是: OCUnit和NSBundle
总之,使用:
 [[NSBundle bundleForClass:[self class]] resourcePath] 
或者在你的情况下:
 [[NSBundle bundleForClass:[self class]] resourceURL] 
Swift 2:
 let testBundle = NSBundle(forClass: self.dynamicType) let fileURL = testBundle.URLForResource("imageName", withExtension: "png") XCTAssertNotNil(fileURL) 
Swift 3:
 let testBundle = Bundle(for: type(of: self)) let fileURL = testBundle.url(forResource: "imageName", withExtension: "png") 
Bundle提供了发现configuration的主要path和testingpath的方法:
 @testable import Example class ExampleTests: XCTestCase { func testExample() { let bundleMain = Bundle.main let bundleDoingTest = Bundle(for: type(of: self )) let bundleBeingTested = Bundle(identifier: "com.example.Example")! print("bundleMain.bundlePath : \(bundleMain.bundlePath)") // …/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Agents print("bundleDoingTest.bundlePath : \(bundleDoingTest.bundlePath)") // …/PATH/TO/Debug/ExampleTests.xctest print("bundleBeingTested.bundlePath : \(bundleBeingTested.bundlePath)") // …/PATH/TO/Debug/Example.app print("bundleMain = " + bundleMain.description) // Xcode Test Agent print("bundleDoingTest = " + bundleDoingTest.description) // Test Case Bundle print("bundleUnderTest = " + bundleBeingTested.description) // App Bundle 
  Xcode 6 | 7 | 8的URL将在Developer/Xcode/DerivedData类似… 
 file:///Users/ UserName/ Library/ Developer/ Xcode/ DerivedData/ App-qwertyuiop.../ Build/ Products/ Debug-iphonesimulator/ AppTests.xctest/ imageName.png 
  …与Developer/CoreSimulator/Devices URL分开 
 file:///Users/ UserName/ Library/ Developer/ CoreSimulator/ Devices/ _UUID_/ data/ Containers/ Bundle/ Application/ _UUID_/ App.app/ 
另请注意,unit testing可执行文件默认情况下与应用程序代码链接。 但是,unit testing代码只能在testing包中拥有目标成员资格。 应用程序代码应该只在应用程序包中具有目标成员资格。 在运行时,unit testing目标包被注入到应用程序包中执行 。
只是为了追加到正确的答案,这是示例如何获得您的UnitTests /支持文件中的文件filePath:
 NSString *filePath = [[[NSBundle bundleForClass:[self class]] resourcePath] stringByAppendingPathComponent:@"YourFileName.json"]; XCTAssertNotNil(filePath); 
这可能对某人有用。
- 您可以像在任何目标中一样引用包文件。
- 检查文件是否被复制到testing目标的复制包资源构build阶段
- 
要访问本地文件: NSURL*imageUrl=[[NSBundle mainBundle]URLForResource:@"imageName" withExtension:@"png"];
您可以使用以下方法进行asynchronous访问并等待响应: https : //github.com/travisjeffery/TRVSMonitor
如果您在testing目标(2)中添加了:dataset1.json:
  NSString *p=[[NSBundle mainBundle] pathForResource:@"dataset1" ofType:@"json"]; NSLog(@"%@",p); 2013-10-29 15:49:30.547 PlayerSample[13771:70b] WT(0): /Users/bpds/Library/Application Support/iPhone Simulator/7.0/Applications/7F78780B-684A-40E0-AA35-A3B5D8AA9DBD/PlayerSample.app.app/dataset1.json 
我遇到的问题是应用程序代码尝试访问bundleIdentifier之类的主包,由于主包不是我的unit testing项目,它将返回零。
在Swift 3.0.1和Objective-C中都可以使用的方法是在NSBundle上创build一个Objective-C类别,并将其包含在unit testing项目中。 你不需要桥头或任何东西。 这个类将被加载,现在当你的应用程序代码要求主包时,你的类将返回unit testing包。
 @interface NSBundle (MainBundle) +(NSBundle *)mainBundle; @end @implementation NSBundle (Main) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" +(NSBundle *)mainBundle { return [NSBundle bundleForClass:[SomeUnitTest class]]; } #pragma clang diagnostic pop @end 
这里是Swift版本,Xcode 7,iOS 9等
 let testBundle = NSBundle(forClass: self.dynamicType) let path = testBundle.pathForResource("someImage", ofType: "jpg") XCTAssertNotNil(path) 
注意:someImage.jpg必须包含在您的testing目标中。