在 xcode 单元测试中加载文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19151420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 03:59:51  来源:igfitidea点击:

Load files in xcode unit tests

xcodeunit-testingnsbundle

提问by ArdenDev

I have an Xcode 5 unit test project and some test xml files related to it. I've tried a bunch of approaches but I can't seem to load the xml files.

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

I've tried the following which does not work

我试过以下不起作用

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

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

Also if I try to preview all the bundles using [NSBundle allBundles] the unit test bundle does not appear in the list?

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

I tried to create a separate resource bundle and I can't seem to locate it programmatically although it does get built and deployed.

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

What am I doing wrong ?

我究竟做错了什么 ?

回答by sash

When running tests the application bundle is still the main bundle. You need to use unit tests bundle.

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

Objective C:

目标 C:

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

Swift 2:

斯威夫特 2:

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

Swift 3 and up:

Swift 3 及更高版本:

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

回答by MarkHim

With swift Swift 3 the syntax self.dynamicTypehas been deprecated, use this instead

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
}

or

或者

guard let ressourceURL = testBundle.url(forResource: "TestData", withExtension: "xml")

回答by stevo.mit

As stated in this answer:

如本答案所述

When the unit test harness runs your code, your unit test bundle is NOTthe main bundle. Even though you are running tests, not your application, your application bundle is still the main bundle.

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

If you use following code, then your code will search the bundle that your unit test class is in, and everything will be fine.

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

Objective C:

目标 C:

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

Swift:

迅速:

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

回答by Peter Hosey

Relative paths are relative to the current working directory. By default, that's / — the root directory. It's looking for that folder at the root level of your startup disk.

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

The correct way to get a resource that's within your bundle is to ask your bundle for it.

获取捆绑包中资源的正确方法是向捆绑包索取它。

In an application, you'd get the bundle using [NSBundle mainBundle]. I don't know if that works in a test case; try it, and if it doesn't (if it returns nilor an unuseful bundle object), substitute [NSBundle bundleForClass:[self class]].

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

Either way, once you have the bundle, you can ask it for the path or URL for a resource. You generally should go for URLs unless you have a very specific reason to need a path (like passing it to a command-line tool using NSTask). Send the bundle a URLForResource:withExtension:message to get the resource's URL.

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

Then, for the purpose of reading a string from it, use [NSString stringWithContentsOfURL:encoding:error:], passing the URL you got from the bundle.

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

回答by Joseph Francis

I know this specific question is asking for xmlfiles, but if you're trying to do the same with json files, try this:

我知道这个特定的问题是要求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") }

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") }

回答by zdravko zdravkin

  1. Get main bundle
  2. Use main bundle to get local mock data
  3. Load data from JSON
  1. 获取主包
  2. 使用主包获取本地模拟数据
  3. 从 JSON 加载数据

let mainBundle = Bundle(identifier: "com.mainBundle.Identifier")

让 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")
        }
    }