-
|
Hi, I want some help to understand how properly have factories with defaults for Working Example Context
Types and factory definitionprotocol FeatureFlagListProtocol {
subscript(featureFlag: FeatureFlag) -> Bool { get }
func loadFeatureFlags() async
func setLocalOverride(for featureFlag: FeatureFlag, isOn: Bool)
}
class DebugFeatureFlagList: FeatureFlagListProtocol {
private var currentFlagValues: [FeatureFlag: Bool]
//.. implementation not relevant
}
class FeatureFlagList: FeatureFlagListProtocol, ObservableObject {
//.. implementation not relevant
}import FactoryKit
import SwiftUI
extension Container {
var featureFlagList: Factory<any FeatureFlagListProtocol> {
self {
print("---- original")
return FeatureFlagList()
}
.cached
}
}Usage in a view modelimport FactoryKit
class FeatureViewModel: ObservableObject {
@Injected(\.featureFlagList) var featureFlags
// implementation
}Where I would use a factory in a test like import FactoryKit
import FactoryTesting
import Foundation
@testable import MyApp
import Testing
@Suite
struct FeatureViewModelTests {
var viewModel: FeatureViewModel
let featureFlags: DebugFeatureFlagList
init() throws {
Container.shared.manager.logger = {
print("----- Factory: \($0)")
}
Container.shared.manager.trace.toggle()
let featureFlags = DebugFeatureFlagList()
Container.shared
.featureFlagList
.register(factory: {
print("---------- override normal factory")
return featureFlags
})
self.featureFlags = featureFlags
}
@Test(.container)
func testInitialise() async throws {
featureFlags.setLocalOverride(for: .isMultipleDeviceHandlingEnabled, isOn: true)
#expect(featureFlags[.isMultipleDeviceHandlingEnabled])
// do more checks on my view model
}
}That would work as expected. Logs
So this works fine ✅ Using ScopesI want to make the following changes to make sure all test have default factory and override it on the test if needed For the factory definition import FactoryKit
import SwiftUI
extension Container {
var featureFlagList: Factory<any FeatureFlagListProtocol> {
self {
print("---- original")
return FeatureFlagList()
}
+ .onTest(factory: {
+ let value = DebugFeatureFlagList()
+ print("---- test factory \(value.debugIdentity)")
+ return value
+ })
.cached
}
}Then, on the test import FactoryKit
import FactoryTesting
import Foundation
@testable import MyApp
import Testing
@Suite
struct FeatureViewModelTests {
var viewModel: FeatureViewModel
let featureFlags: DebugFeatureFlagList
init() throws {
Container.shared.manager.logger = {
print("----- Factory: \($0)")
}
Container.shared.manager.trace.toggle()
let featureFlags = DebugFeatureFlagList()
Container.shared
.featureFlagList
.register(factory: {
print("---------- override normal factory")
return featureFlags
})
+ .onTest(factory: {
+ print("---------- overriden test factory")
+ return featureFlags
+ })
+ .reset(.scope)
self.featureFlags = featureFlags
}
@Test(.container)
func testInitialise() async throws {
featureFlags.setLocalOverride(for: .isMultipleDeviceHandlingEnabled, isOn: true)
#expect(featureFlags[.isMultipleDeviceHandlingEnabled])
// do more checks on my view model
}
}This doesn't work as expected. My logs would show something like: Log content
What am I missing? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
Ok, I went deep reading the source code to understand what's going on. First, there was documentation for my problem in https://hmlongco.github.io/Factory/documentation/factorykit/modifiers When I define an
Later in the same document it mentions
Which is the solution for the "default" -- Also since my factory also used the So with both 1️⃣ and 2️⃣ I end up with the expected behavior. My main issue was not understanding the difference between factory definitions, registrations and resolutions. |
Beta Was this translation helpful? Give feedback.
Ok,
I went deep reading the source code to understand what's going on.
First, there was documentation for my problem in https://hmlongco.github.io/Factory/documentation/factorykit/modifiers
When I define an
onTestmodifier in a Factory Definition withclosure A. Even though later I would register a newonTestfor the same factory withclosure B. When resolving the factoryclosure Awill be executed as explained by the lines:Later in the same document it mentions