我有一个Xcode 5单元测试项目和一些与之相关的测试xml文件。我已经尝试了一些方法,但我似乎无法加载xml文件。
我尝试过以下无效的
NSData* nsData = [NSData dataWithContentsOfFile:@"TestResource/TestData.xml"];
NSString* fileString = [NSString stringWithContentsOfFile:@"TestData.xml" encoding:NSUTF8StringEncoding error:&error];
此外,如果我尝试使用[NSBundle allBundles]预览所有捆绑包,单元测试包不会出现在列表中?
我尝试创建一个单独的资源包,但我似乎无法以编程方式找到它,尽管它已经构建和部署。
我做错了什么?
答案 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)
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)
我在这里找不到任何最新的答案或使用 URL。
首先将以下函数添加到您的 testClass 中:
func test() throws {
let xmlData = Self.getFile("TestData", withExtension: "xml")
XCTAssertNotNil(xmlData, "File not found")
}
然后你可以像这样在你的测试类中调用它:
{{1}}
注意:出于安全原因,Apple 建议始终将 URL 用于资源(而不是路径)。