web-dev-qa-db-fra.com

Charger des fichiers dans les tests unitaires xcode

J'ai un projet de test unitaire Xcode 5 et quelques fichiers xml de test qui s'y rapportent. J'ai essayé un tas d'approches mais je n'arrive pas à charger les fichiers xml.

J'ai essayé ce qui suit qui ne fonctionne pas

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

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

De plus, si j'essaie de prévisualiser tous les bundles à l'aide de [NSBundle allBundles], le bundle de test unitaire n'apparaît pas dans la liste?

J'ai essayé de créer un ensemble de ressources distinct et je n'arrive pas à le localiser par programme bien qu'il soit créé et déployé.

Qu'est-ce que je fais mal ?

55
ArdenDev

Lors de l'exécution de tests, le bundle d'application est toujours le bundle principal. Vous devez utiliser le bundle de tests unitaires.

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

Swift 3:

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

Avec Swift Swift 3 la syntaxe self.dynamicType est obsolète, utilisez-le à la place

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
}

ou

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

Comme indiqué dans ce réponse :

Lorsque le faisceau de tests unitaires exécute votre code, votre bundle de tests unitaires est [~ # ~] et non [~ # ~] le bundle principal. Même si vous exécutez des tests, pas votre application, votre bundle d'application est toujours le bundle principal.

Si vous utilisez le code suivant, votre code recherchera l'ensemble dans lequel se trouve votre classe de test unitaire, et tout ira bien.

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

Les chemins relatifs sont relatifs au répertoire de travail actuel. Par défaut, c'est/- le répertoire racine. Il recherche ce dossier au niveau racine de votre disque de démarrage.

La bonne façon d'obtenir une ressource qui fait partie de votre bundle est de la demander à votre bundle.

Dans une application, vous obtiendrez l'ensemble en utilisant [NSBundle mainBundle]. Je ne sais pas si cela fonctionne dans un cas de test; essayez-le, et si ce n'est pas le cas (s'il renvoie nil ou un objet bundle inutile), remplacez [NSBundle bundleForClass:[self class]].

Dans les deux cas, une fois que vous avez le bundle, vous pouvez lui demander le chemin ou l'URL d'une ressource. Vous devez généralement opter pour des URL, sauf si vous avez une raison très spécifique d'avoir besoin d'un chemin (comme le passer à un outil en ligne de commande à l'aide de NSTask). Envoyez un paquet URLForResource:withExtension: message pour obtenir l'URL de la ressource.

Ensuite, pour en lire une chaîne, utilisez [NSString stringWithContentsOfURL:encoding:error:], en transmettant l'URL que vous avez obtenue du bundle.

2
Peter Hosey