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); 

这可能对某人有用。

  1. 您可以像在任何目标中一样引用包文件。
  2. 检查文件是否被复制到testing目标的复制包资源构build阶段
  3. 要访问本地文件:

     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目标中。