在xcode单元测试中加载文件

时间:2013-10-03 05:25:50

标签: xcode unit-testing nsbundle

我有一个Xcode 5单元测试项目和一些与之相关的测试xml文件。我已经尝试了一些方法,但我似乎无法加载xml文件。

我尝试过以下无效的

NSData* nsData = [NSData dataWithContentsOfFile:@"TestResource/TestData.xml"];

NSString* fileString = [NSString stringWithContentsOfFile:@"TestData.xml" encoding:NSUTF8StringEncoding error:&error];

此外,如果我尝试使用[NSBundle allBundles]预览所有捆绑包,单元测试包不会出现在列表中?

我尝试创建一个单独的资源包,但我似乎无法以编程方式找到它,尽管它已经构建和部署。

我做错了什么?

8 个答案:

答案 0 :(得分:90)

运行测试时,应用程序包仍然是主要的捆绑包。您需要使用单元测试包。

目标C:

NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:@"TestData" ofType:@"xml"];
NSData *xmlData = [NSData dataWithContentsOfFile:path];

Swift 2:

let bundle = NSBundle(forClass: self.dynamicType)
let path = bundle.pathForResource("TestData", ofType: "xml")!
let xmlData = NSData(contentsOfFile: path)

斯威夫特3:

let bundle = Bundle(for: type(of: self))
let path = bundle.path(forResource: "TestData", ofType: "xml")!
let xmlData = NSData(contentsOfFile: path) 

答案 1 :(得分:9)

使用swift Swift 3时,语法已被弃用,请改用

self.dynamicType

let testBundle = Bundle(for: type(of: self))
guard let ressourceURL = testBundle.url(forResource: "TestData", ofType: "xml") else {
    // file does not exist
    return
}
do {
    let ressourceData = try Data(contentsOf: ressourceURL)
} catch let error {
    // some error occurred when reading the file
}

答案 2 :(得分:7)

answer中所述:

当单元测试工具运行您的代码时,您的单元测试包是主包。即使您正在运行测试,而不是您的应用程序,您的应用程序包仍然是主要的捆绑包。

如果您使用以下代码,那么您的代码将搜索您的单元测试类所在的包,并且一切都会正常。

目标C:

NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:@"TestData" ofType:@"xml"];
NSData *xmlData = [NSData dataWithContentsOfFile:path];

<强>夫特:

let bundle = NSBundle(forClass: self.dynamicType)
if let path = bundle.pathForResource("TestData", ofType: "xml")
{
    let xmlData = NSData(contentsOfFile: path)
}

答案 3 :(得分:2)

相对路径相对于当前工作目录。默认情况下,这是/ - 根目录。它正在启动磁盘的根级别查找该文件夹。

获取捆绑资源的正确方法是向您的捆绑包询问。

在应用程序中,您将使用[NSBundle mainBundle]获取捆绑包。我不知道这是否适用于测试用例;尝试它,如果没有(如果它返回nil或无用的包对象),请替换[NSBundle bundleForClass:[self class]]

无论哪种方式,一旦拥有了捆绑包,就可以向它询问资源的路径或URL。除非您有非常具体的理由需要路径(例如使用NSTask将其传递给命令行工具),否则通常应该使用URL。发送包URLForResource:withExtension:消息以获取资源的URL。

然后,为了从中读取字符串,请使用[NSString stringWithContentsOfURL:encoding:error:],传递从包中获取的URL。

答案 4 :(得分:0)

我知道这个特定的问题正在询问xml文件,但是如果您要对json文件进行相同的操作,请尝试以下操作:

let url = Bundle.main.url(forResource: "data", withExtension: ".json") guard let dataURL = url, let data = try? Data(contentsOf: dataURL) else { fatalError("Couldn't read data.json file") }

答案 5 :(得分:0)

  1. 获取主捆绑包
  2. 使用主捆绑包获取本地模拟数据
  3. 从JSON加载数据

let mainBundle = Bundle(标识符:“ com.mainBundle.Identifier”)

if let path = mainBundle?.path(forResource: "mockData", ofType: "json") {
        do {
            let testData = try Data(contentsOf: URL(fileURLWithPath: path))
            networkTestSession.data = testData
        } catch {
            debugPrint("local json test data missing")
        }
    }

答案 6 :(得分:0)

需要注意的一件事是(浪费我的服务时间来弄清楚它):

别忘了将测试文件添加到构建阶段的“复制捆绑包资源”部分中

没有它,您将无法成功加载文件。

答案 7 :(得分:0)

Swift 4+

我在这里找不到任何最新的答案或使用 URL。

首先将以下函数添加到您的 testClass 中:

func test() throws {
    let xmlData = Self.getFile("TestData", withExtension: "xml")
    XCTAssertNotNil(xmlData, "File not found")
}

然后你可以像这样在你的测试类中调用它:

{{1}}

注意:出于安全原因,Apple 建议始终将 URL 用于资源(而不是路径)。