Unit Testing with Swift Data

Hi,

I'm wondering if anyone has a suggestion as to how to access a ModelContainer in the Unit Testing class.

I tried making a class to only instantiate the model container once, but it seems that Xcode is running this class in two different contexts (and they don't communicate): once when the test launches and then again from inside the XCTestCase subclass. If I try to save, I get an error about the two containers not being the same or a ton of validation errors.

Appreciate any help to point me in the right direction.

import SwiftUI
import SwiftData

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(MyModelContainer.shared.container)
    }
}
@MainActor
final class MyModelContainer {
    private init() { }

    @MainActor
    static var shared = MyModelContainer()
    var container: ModelContainer {
        if let internalContainer {
            return internalContainer
        }

        let schema = Schema([
            MyModel.self
        ])

        if ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil {
            // testing
            internalContainer = previewContext(with: schema)
        } else if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" {
            // previewing
            internalContainer = previewContext(with: schema)
        } else {
            // production
            internalContainer = productionContext(with: schema)
        }
        return internalContainer!
    }

    private var internalContainer: ModelContainer?

    private func previewContext(with schema: Schema) -> ModelContainer {

        let modelConfiguration = ModelConfiguration(schema: schema,
                                                    isStoredInMemoryOnly: true)

        do {
            let previewData = fetchPreviewData()

            let container = try ModelContainer(for: schema, configurations: [modelConfiguration])
            let context = container.mainContext
            context.insert(previewData)

            try context.save()
            print("Loaded preview Container \(Date.now)")
            return container
        } catch {
            print("Could not create ModelContainer: \(error)")
            fatalError("Could not create ModelContainer: \(error)")
        }
    }

    func productionContext(with schema: Schema) -> ModelContainer {
        let modelConfiguration = ModelConfiguration(schema: schema,
                                                    isStoredInMemoryOnly: false)

        do {
            print("Loaded FlashMeContainer")
            return try ModelContainer(for: schema, configurations: [modelConfiguration])
        } catch {
            fatalError("Could not create ModelContainer: \(error)")
        }
    }
}
final class FlashMeTests: XCTestCase {
    @MainActor func testImport() throws {
        let data = NSDataAsset(name: "myCodableModelData")?.data
        let myCodableModel = try oldData!.decode(as: MyCodableModel.self)
        let myModel = myCodableModel.convertToSwiftData()
        let context = MyModelContainer.shared.container.mainContext
        context.insert(myModel)
        try context.save(myModel)
    }
}

Hi, I create a ModelContainer in test class.

final class NewNotPaidTrTest: XCTestCase {
    @MainActor
    let testContainer: ModelContainer = {
        do {
            let container = try ModelContainer (for: Category.self, Account.self, Transaction.self, configurations: ModelConfiguration(isStoredInMemoryOnly: true))
            
            container.mainContext.insert(Category.preview)
            container.mainContext.insert(Account.preview)
            
            return container
        } catch {
            fatalError("Failed to create container")
        }
    }()
    
    @MainActor func testNewNotPaidTr() throws {
        let tr = Transaction(amount: 1000, date: Date.now, notes: "", isMovement: false, isPaid: false, planAuto: false)
        
        debugPrint(Account.preview.name)
        
        testContainer.mainContext.insert(tr)
        tr.account = Account.preview
        tr.category = Category.preview
        
        Account.updateBalance(tr, isAddTr: true)

        XCTAssertEqual(tr.account!.balance, 123400, "Fallita -> \(tr.account!.balance)")
        

        do {
            try testContainer.mainContext.save()
        } catch {
            fatalError("Failed to save")
        }
        
        testContainer.mainContext.delete(tr)
        Account.updateBalance(tr, isAddTr: false)
        XCTAssertEqual(tr.account!.balance, 123400, "Fallita -> \(tr.account!.balance)")
        
    }

}   
Unit Testing with Swift Data
 
 
Q