2
2

More than 1 year has passed since last update.

【iOS】UnitTestプロジェクトのディレクトリ内にあるJSONファイルのロード方法

Posted at

課題

UnitTestをする時にテストデータのJSONファイルを、アプリ本体のディレクトリではなく、UnitTestのディレクトリに配置し、Test実行時に読み込もうとしたら、上手く読み込みができなくてハマったので解決方法を記事にしました。

今回やろうとしたことは、画像で見ていただいたほうが早いかもしれません。
スクリーンショット 2022-02-21 16.30.57.png

上記のように、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を参考にして解決しました。

今回は、以上となります。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2