web-dev-qa-db-ja.com

Xcodeユニットテストでファイルをロードする

Xcode 5単体テストプロジェクトとそれに関連するいくつかのテストxmlファイルがあります。たくさんのアプローチを試しましたが、xmlファイルをロードできないようです。

動作しない以下を試しました

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

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

また、[NSBundle allBundles]を使用してすべてのバンドルをプレビューしようとすると、ユニットテストバンドルがリストに表示されませんか?

個別のリソースバンドルを作成しようとしましたが、ビルドおよびデプロイされますが、プログラムで見つけることはできません。

私は何を間違えていますか?

55
ArdenDev

テストを実行するとき、アプリケーションバンドルは依然としてメインバンドルです。単体テストバンドルを使用する必要があります。

目的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) 
92
sash

With 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
}

または

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

これで述べられているように answer

ユニットテストハーネスがコードを実行するとき、ユニットテストバンドルは[〜#〜] not [〜#〜]メインバンドルです。アプリケーションではなくテストを実行している場合でも、アプリケーションバンドルは依然としてメインバンドルです。

次のコードを使用する場合、コードはユニットテストクラスが含まれているバンドルを検索し、すべてが正常に実行されます。

目的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)
}
7
stevo.mit

相対パスは、現在の作業ディレクトリからの相対パスです。デフォルトでは、これは/ —ルートディレクトリです。起動ディスクのルートレベルでそのフォルダーを探しています。

バンドル内にあるリソースを取得する正しい方法は、バンドルを要求することです。

アプリケーションでは、[NSBundle mainBundle]を使用してバンドルを取得します。テストケースで機能するかどうかはわかりません。それを試して、もしそれが(nilまたは使用できないバンドルオブジェクトを返す場合)、[NSBundle bundleForClass:[self class]]を置き換えてください。

いずれにしても、バンドルを入手したら、リソースのパスまたはURLを要求できます。パスを必要とする非常に具体的な理由がない限り、通常はURLにアクセスする必要があります(NSTaskを使用してコマンドラインツールにパスを渡すなど)。バンドルにURLForResource:withExtension:メッセージを送信して、リソースのURLを取得します。

次に、文字列を読み取るために、[NSString stringWithContentsOfURL:encoding:error:]を使用して、バンドルから取得したURLを渡します。

2
Peter Hosey