بنقرة واحدة
testing-reducer
How to write unit tests for a OneWay Reducer using existing patterns
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
How to write unit tests for a OneWay Reducer using existing patterns
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Guides the creation and testing of Reducers and Stores using the OneWay library and Clean Architecture in the Badabook project. Use this skill when implementing new features or fixing bugs in the App layer that involve state management.
Generates SwiftData entities, repositories, and use cases following the project's Clean Architecture and modular structure. Use this skill when the user wants to add new data entities or create a complete data layer for a new feature.
| name | testing-reducer |
| description | How to write unit tests for a OneWay Reducer using existing patterns |
This skill describes how to write comprehensive unit tests for a OneWay Reducer.
Follow these instructions to test all actions defined in the Reducer.Action enum.
Reducer file available.BadaTesting module or similar testing utilities available (e.g., Store, UseCaseContainer).<ReducerName>Tests.swift.Use the following template for your test file. Replace <ReducerName> with the actual name of your reducer.
import BadaCore
import BadaDomain
import BadaTesting
@testable import BadaApp // Or the module containing the Reducer
@Suite
struct <ReducerName>Tests {
// 1. Setup Dependencies (Mocks)
init() {
// Register default mock use cases here
UseCaseContainer.instance.register {
// ...
}
UseCaseContainer.instance.register {
// ...
}
}
// 2. Test Cases will go here
}
Rule: Every case in the Reducer.Action enum MUST have a corresponding test function.
Rule: The name of the test function MUST match the case name of the action.
For each action case:
Define the Test Function:
@Test
func <actionCaseName>() async {
// ...
}
Arrange (Setup State and Dependencies):
await UseCaseContainer.$instance.withValue(container) { ... } to scope the dependencies.container inside the test.let container = UseCaseContainer()
container.register {
// ...
}
container.register {
// ...
}
await UseCaseContainer.$instance.withValue(container) {
let sut = Store(
reducer: <ReducerName>(),
state: <ReducerName>.State(
// Set initial state values relevant to the test
)
)
// 3. Act & Assert inside the closure
await sut.send(.<actionCaseName>(<arguments>))
await sut.expect(\.someProperty, expectedValue)
}
Reducer Action:
enum Action {
case setCount(Int)
case fetchUser
}
Test Implementation:
@Suite
struct MyReducerTests {
init() {
UseCaseContainer.instance.register {
GetUserUseCase { .success(User(name: "Default")) }
}
}
@Test
func setCount() async {
let sut = Store(
reducer: MyReducer(),
state: MyReducer.State()
)
await sut.send(.setCount(10))
await sut.expect(\.count, 10)
}
@Test
func fetchUser() async {
// Override mock if needed for this specific test
let container = UseCaseContainer()
container.register {
GetUserUseCase { .success(User(name: "Alice")) }
}
await UseCaseContainer.$instance.withValue(container) {
let sut = Store(
reducer: MyReducer(),
state: MyReducer.State()
)
await sut.send(.fetchUser)
await sut.expect(\.user, User(name: "Alice"))
}
}
}
make test@Test function for every case in Action?Action case names exactly?sut.expect?