Skip to content

Commit 809c3bb

Browse files
authored
[Fix] Check the state does not actually change when no changes are expected (#1161)
* fix: check the state doesn’t change when the modify closure is nil * test: add tests for the 'unexpected changes on the state' failure
1 parent 5af88eb commit 809c3bb

File tree

2 files changed

+61
-4
lines changed

2 files changed

+61
-4
lines changed

Sources/ComposableArchitecture/TestSupport/TestStore.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,10 @@
401401
file: StaticString,
402402
line: UInt
403403
) throws {
404-
guard let modify = modify else { return }
405404
let current = expected
406-
try modify(&expected)
405+
if let modify = modify {
406+
try modify(&expected)
407+
}
407408

408409
if expected != actual {
409410
let difference =
@@ -417,16 +418,19 @@
417418
\(String(describing: actual).indent(by: 2))
418419
"""
419420

421+
let messageHeading = modify != nil ?
422+
"A state change does not match expectation" :
423+
"State was not expected to change, but a change occurred"
420424
XCTFail(
421425
"""
422-
A state change does not match expectation: …
426+
\(messageHeading): …
423427
424428
\(difference)
425429
""",
426430
file: file,
427431
line: line
428432
)
429-
} else if expected == current {
433+
} else if expected == current && modify != nil {
430434
XCTFail(
431435
"""
432436
Expected state to change, but no change occurred.

Tests/ComposableArchitectureTests/TestStoreFailureTests.swift

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,59 @@ class TestStoreFailureTests: XCTestCase {
6262
}
6363
}
6464

65+
func testUnexpectedStateChangeOnSendFailure() {
66+
struct State: Equatable { var count = 0 }
67+
let store = TestStore(
68+
initialState: .init(),
69+
reducer: Reducer<State, Void, Void> { state, action, _ in state.count += 1
70+
return .none
71+
},
72+
environment: ()
73+
)
74+
75+
XCTExpectFailure {
76+
store.send(())
77+
} issueMatcher: {
78+
$0.compactDescription == """
79+
State was not expected to change, but a change occurred: …
80+
81+
− TestStoreFailureTests.State(count: 0)
82+
+ TestStoreFailureTests.State(count: 1)
83+
84+
(Expected: −, Actual: +)
85+
"""
86+
}
87+
}
88+
89+
func testUnexpectedStateChangeOnReceiveFailure() {
90+
struct State: Equatable { var count = 0 }
91+
enum Action { case first, second }
92+
let store = TestStore(
93+
initialState: .init(),
94+
reducer: Reducer<State, Action, Void> { state, action, _ in
95+
switch action {
96+
case .first: return .init(value: .second)
97+
case .second: state.count += 1; return .none
98+
}
99+
},
100+
environment: ()
101+
)
102+
103+
store.send(.first)
104+
XCTExpectFailure {
105+
store.receive(.second)
106+
} issueMatcher: {
107+
$0.compactDescription == """
108+
State was not expected to change, but a change occurred: …
109+
110+
− TestStoreFailureTests.State(count: 0)
111+
+ TestStoreFailureTests.State(count: 1)
112+
113+
(Expected: −, Actual: +)
114+
"""
115+
}
116+
}
117+
65118
func testReceivedActionAfterDeinit() {
66119
XCTExpectFailure {
67120
do {

0 commit comments

Comments
 (0)