課題
UnitTestをする時にテストデータのJSONファイルを、アプリ本体のディレクトリではなく、UnitTestのディレクトリに配置し、Test実行時に読み込もうとしたら、上手く読み込みができなくてハマったので解決方法を記事にしました。
今回やろうとしたことは、画像で見ていただいたほうが早いかもしれません。
上記のように、QiitaPracticeTests
(UnitTest)のディレクトリ直下にテストデータ(JSONファイル)を配置している状態。
これをやる理由としては、テストでしか使わないデータを、アプリ本体のプロジェクトに入れたくないからです。
→ 混乱するので、テストデータはテストディレクトリにしか入れたくない。
エラーになるコード
class QiitaPracticeTests: XCTestCase {
private func loadJson(fileName: String) -> Menu {
let data: Data
// ファイルの存在チェック・取得
guard let file = Bundle.main.url(forResource: fileName, withExtension: nil) else {]
// ↓ここに入ってエラーになります。
fatalError("\(fileName) が存在しません")
}
// ファイルの読み込み
do {
data = try Data(contentsOf: file)
} catch {
fatalError("\(fileName) の読み込みに失敗しました。\n\(error.localizedDescription)")
}
do {
let decoder = JSONDecoder()
let object = try decoder.decode(Menu.self, from: data)
return object
} catch {
fatalError("デコードに失敗しました。\n\(error.localizedDescription)")
}
}
func testExample() throws {
let menu = loadJson(fileName: "menu.json")
print(menu)
}
}
testExample()
を実行すると、ディレクトリにあるファイルを見つけられずに、
fatalError("\(fileName) が存在しません")
のところに入ってしまいます。
原因
Bundle.main
としてしまうのが、問題の原因です。
上記では、テストプロジェクトにある、リソースを取得できないようです。
解決方法
Bundle.main.url(forResource: fileName, withExtension: nil)
の1行を、
Bundle(for: QiitaPracticeTests.self).url(forResource: fileName, withExtension: nil)
と修正するれば、ファイルが取得でき、期待通りに動くようになります。
QiitaPracticeTests
は、メソッドを実行する対象のクラス名になります。
上記のstackoverflowを参考にして解決しました。
今回は、以上となります。