You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -6,6 +6,29 @@ The OSF Angular project uses a modular and mock-driven testing strategy. A share
6
6
7
7
---
8
8
9
+
### Pro-tips
10
+
11
+
**What to test**
12
+
13
+
The OSF Angular testing strategy enforces 100% coverage while also serving as a guardrail for future engineers. Each test should highlight the most critical aspect of your code — what you’d want the next developer to understand before making changes. If a test fails during a refactor, it should clearly signal that a core feature was impacted, prompting them to investigate why and preserve the intended behavior.
14
+
15
+
---
16
+
17
+
**Test Data**
18
+
19
+
The OSF Angular Test Data module provides a centralized and consistent source of data across all unit tests. It is intended solely for use within unit tests. By standardizing test data, any changes to underlying data models will produce cascading failures, which help expose the full scope of a refactor. This is preferable to isolated or hardcoded test values, which can lead to false positives and missed regressions.
20
+
21
+
The strategy for structuring test data follows two principles:
22
+
23
+
1. Include enough data to cover all relevant permutations required by the test suite.
24
+
2. Ensure the data reflects all possible states (stati) of the model.
25
+
26
+
**Test Scope**
27
+
28
+
The OSF Angular project defines a `@testing` scope that can be used for importing all testing-related modules.
29
+
30
+
---
31
+
9
32
## Index
10
33
11
34
-[Best Practices](#best-practices)
@@ -34,8 +57,8 @@ The OSF Angular project uses a modular and mock-driven testing strategy. A share
|`osf.testing.module.ts`| Unified test module for shared imports |
37
-
|`mocks/*.mock.ts`| Mock services and tokens |
38
-
|`data/*.data.ts`| Static mock data for test cases |
60
+
|`src/mocks/*.mock.ts`| Mock services and tokens |
61
+
|`src/data/*.data.ts`| Static mock data for test cases |
39
62
40
63
---
41
64
@@ -93,15 +116,15 @@ This guarantees **test integrity in CI** and **prevents regressions**.
93
116
94
117
## Key Structure
95
118
96
-
### `testing/osf.testing.module.ts`
119
+
### `src/testing/osf.testing.module.ts`
97
120
98
121
This module centralizes commonly used providers, declarations, and test utilities. It's intended to be imported into any `*.spec.ts` test file to avoid repetitive boilerplate.
-`StoreMock` – mocks NgRx Store for selector and dispatch testing.
142
165
-`ToastServiceMock` – injects a mock version of the UI toast service.
143
166
144
-
### `testing/mocks/`
167
+
### Testing Mocks
145
168
146
-
Provides common service and token mocks to isolate unit tests from real implementations.
169
+
The `src/testing/mocks/` directory provides common service and token mocks to isolate unit tests from real implementations.
147
170
148
171
**examples**
149
172
@@ -154,11 +177,16 @@ Provides common service and token mocks to isolate unit tests from real implemen
154
177
155
178
---
156
179
157
-
### `testing/data/`
180
+
### Test Data
158
181
159
-
Includes fake/mock data used by tests to simulate external API responses or internal state.
182
+
The `src/testing/data/` directory includes fake/mock data used by tests to simulate external API responses or internal state.
160
183
161
-
Only use data from the `testing/data` data mocks to ensure that all data is the centralized.
184
+
The OSF Angular Test Data module provides a centralized and consistent source of data across all unit tests. It is intended solely for use within unit tests. By standardizing test data, any changes to underlying data models will produce cascading failures, which help expose the full scope of a refactor. This is preferable to isolated or hardcoded test values, which can lead to false positives and missed regressions.
185
+
186
+
The strategy for structuring test data follows two principles:
187
+
188
+
1. Include enough data to cover all relevant permutations required by the test suite.
189
+
2. Ensure the data reflects all possible states (stati) of the model.
162
190
163
191
**examples**
164
192
@@ -169,11 +197,13 @@ Only use data from the `testing/data` data mocks to ensure that all data is the
169
197
170
198
---
171
199
172
-
---
173
-
174
200
## Testing Angular Services (with HTTP)
175
201
176
-
All OSF Angular services that make HTTP requests must be tested using `HttpClientTestingModule` and `HttpTestingController`.
202
+
All OSF Angular services that make HTTP requests must be tested using `HttpClientTestingModule` and `HttpTestingController`. This testing style verifies both the API call itself and the logic that maps the response into application data.
203
+
204
+
When using HttpTestingController to flush HTTP requests in tests, only use data from the @testing/data mocks to ensure consistency and full test coverage.
The OSF Angular strategy for NGXS state testing is to create **small integration test scenarios**. This is a deliberate departure from traditional **black box isolated** testing. The rationale is:
276
+
277
+
1.**NGXS actions** tested in isolation are difficult to mock and result in garbage-in/garbage-out tests.
278
+
2.**NGXS selectors** tested in isolation are easy to mock but also lead to garbage-in/garbage-out outcomes.
279
+
3.**NGXS states** tested in isolation are easy to invoke but provide no meaningful validation.
280
+
4.**Mocking service calls** during state testing introduces false positives, since the mocked service responses may not reflect actual backend behavior.
281
+
282
+
This approach favors realism and accuracy over artificial test isolation.
283
+
284
+
### Test Outline Strategy
285
+
286
+
1.**Dispatch the primary action** – Kick off the state logic under test.
287
+
2.**Dispatch any dependent actions** – Include any secondary actions that rely on the primary action's outcome.
288
+
3.**Verify the loading selector is `true`** – Ensure the loading state is activated during the async flow.
289
+
4.**Verify the service call using `HttpTestingController` and `@testing/data` mocks** – Confirm that the correct HTTP request is made and flushed with known mock data.
290
+
5.**Verify the loading selector is `false`** – Ensure the loading state deactivates after the response is handled.
291
+
6.**Verify the primary data selector** – Check that the core selector related to the dispatched action returns the expected state.
292
+
7.**Verify any additional selectors** – Assert the output of other derived selectors relevant to the action.
293
+
8.**Validate the test with `httpMock.verify()`** – Confirm that all HTTP requests were flushed and none remain unhandled:
294
+
295
+
```ts
296
+
expect(httpMock.verify).toBeTruthy();
297
+
```
298
+
299
+
### Example
300
+
301
+
This is an example of an NGXS action test that involves both a **primary action** and a **dependent action**. The dependency must be dispatched first to ensure the test environment mimics the actual runtime behavior. This pattern helps validate not only the action effects but also the full selector state after updates. All HTTP requests are flushed using the centralized `@testing/data` mocks.
302
+
303
+
```ts
304
+
it('should test action, state and selectors', inject([HttpTestingController], (httpMock:HttpTestingController) => {
0 commit comments