Thanks for the response!
I don't believe you can send actions into the store like that anymore unless it's a test store. We recently updated the TCA version in our project to 0.47.2 and we ran into issues in these tests where we were previously doing that.
I think your #2 solution is a good approach. I've gone with something slightly simpler for now, which may not work in all our scenarios.
Most of our screens have a few different states, including a logged out. When the screen loads we start by loading the logged in/out state of the user, what happens instantaneously. We only load additional data for logged in users. This is a CurrentValueSubject publisher for a Bool value. Like I showed in my original post, in all these previews we're using a .noop() environment, with instances of the services that don't do anything.
struct PetsScreenLoaded_Previews: PreviewProvider {
static var previews: some View {
PetsScreen(
store: Store(
initialState: PetsState(
loading: false,
pets: Pet.mocks
),
reducer: petsReducer,
environment: .noop()
)
)
.previewDisplayName("Pets Loaded")
}
}
The .noop() environment looks something like this:
extension PetsEnvironment {
public static var noop = PetsEnvironment(
mainQueue: DispatchQueue.main.eraseToAnyScheduler(),
petsAPI: .noop(),
isAuthorized: CurrentValueSubject<Bool, Failure>(false)
)
}
Part of what that environment provides is a mainQueue, on which the responses are all returned:
case .onAppear:
return environment.isAuthorized
.receive(on: environment.mainQueue)
.catchToEffect(PetsActions.authorizationChanged)
case .authorizationChanged(.success(let isAuthorized)):
state.isAuthorized = isAuthorized
state.loading = true
return Effect(value: .getPets)
I've found that by switching the DispatchQueue.main to DispatchQueue.test, the events are stored and the .authorizationChanged(Result) is never fired. This also lets us use a test queue during the snapshot tests, which seems more appropriate.
Looking at this again right now, there might be something we can do directly with the isAuthorized property of the .noop() environment to prevent it from returning a true/false value, such as making the Boolean nullable and using compactMap, but I haven't looked into this.