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
Copy file name to clipboardExpand all lines: content/recipes/suites.md
+27-69Lines changed: 27 additions & 69 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,20 +1,12 @@
1
1
### Suites (formerly Automock)
2
2
3
-
Suites is an opinionated, flexible testing meta-framework aimed at elevating the software testing experience within
4
-
backend systems. By integrating a wide array of testing tools into a cohesive framework, Suites simplifies the process
5
-
of creating reliable tests, thereby ensuring the development of high-quality software.
3
+
Suites is an opinionated and flexible testing meta-framework designed to enhance the software testing experience for backend systems. By bringing together a variety of testing tools into a unified framework, Suites streamlines the creation of reliable tests, helping to ensure the development of high-quality software.
6
4
7
-
> info **Hint**`Suites` is a third-party package and is not managed by the NestJS core team. Please report any issues found with the
8
-
library in the [appropriate repository](https://github.com/suites-dev/suites).
5
+
> info **Hint**`Suites` is a third-party package and is not maintained by the NestJS core team. Please report any issues with the library to the [appropriate repository](https://github.com/suites-dev/suites).
9
6
10
7
#### Introduction
11
8
12
-
Inversion of Control (IoC) is a cornerstone of the NestJS framework, enabling a modular and testable architecture. While
13
-
NestJS provides built-in tools for creating testing modules, Suites offers an alternative approach that focuses on the
14
-
behavior of isolated units or a few units together. Suites operates with a virtual container for dependencies, where mocks
15
-
are automatically generated. This means you don't need to manually replace each provider with a mock in the IoC (or DI)
16
-
container. This approach can be used instead of or alongside the built-in `Test.createTestingModule` method, providing more
17
-
flexibility in unit testing, depending on the case.
9
+
Inversion of Control (IoC) is a fundamental principle in the NestJS framework, enabling a modular, testable architecture. While NestJS offers built-in tools for creating testing modules, Suites provides an alternative approach that emphasizes testing isolated units or small groups of units together. Suites uses a virtual container for dependencies, where mocks are automatically generated, eliminating the need to manually replace each provider with a mock in the IoC (or DI) container. This approach can be used either in place of or alongside NestJS’s `Test.createTestingModule` method, offering more flexibility for unit testing based on your needs.
> info **Hint**`Suites` supports Vitest and Sinon as test doubles as well, `@suites/doubles.vitest` and `@suites/doubles.sinon` respectively.
28
20
29
-
#### Example and Module Setup
30
-
31
-
**Base Module Setup**
21
+
#### Example and module setup
32
22
33
23
Consider a module setup for `CatsService` that includes `CatsApiService`, `CatsDAL`, `HttpClient`, and `Logger`. This
34
24
will be our base for the examples in this recipe:
@@ -46,14 +36,9 @@ import { PrismaModule } from '../prisma.module';
46
36
exportclassCatsModule {}
47
37
```
48
38
49
-
The `HttpModule` and the `PrismaModule` are both exporting providers to the host module.
50
-
51
-
#### Solitary Testing Example
52
-
53
-
**Example: Testing `CatsHttpService`**
39
+
Both the `HttpModule` and `PrismaModule` are exporting providers to the host module.
54
40
55
-
Let's start by testing the `CatsHttpService` in isolation. This service fetches cat data from an API and logs the
56
-
operation:
41
+
Let's start by testing the `CatsHttpService` in isolation. This service is responsible for fetching cat data from an API and logging the operation.
57
42
58
43
```typescript
59
44
@@filename(cats-http.service)
@@ -103,27 +88,19 @@ describe('Cats Http Service Unit Test', () => {
103
88
});
104
89
```
105
90
106
-
**Explanation**
91
+
In the example above, Suites automatically mocks the dependencies of `CatsHttpService` using `TestBed.solitary()`. This makes the setup easier since you don’t have to manually mock each dependency.
107
92
108
-
In the above example, Suites automatically mocks the dependencies of `CatsHttpService` using `TestBed.solitary()`. This
109
-
simplifies the setup, as you don't need to manually mock each dependency.
110
-
111
-
-**Auto-Mocking of Dependencies**: Suites generates mocks for all dependencies of the unit under test.
112
-
-**Empty Behavior of Mocks**: Initially, these mocks have no predefined behavior. You need to specify the behavior as
113
-
required for your tests.
114
-
-**`unit` and `unitRef`** properties:
115
-
-`unit` is the actual instance of the class under test, with its mocked dependencies.
93
+
- Auto-Mocking of Dependencies: Suites generates mocks for all dependencies of the unit being tested.
94
+
- Empty Behavior of Mocks: Initially, these mocks don’t have any predefined behavior. You’ll need to specify their behavior as needed for your tests.
95
+
-`unit` and `unitRef` properties:
96
+
-`unit` refers to the actual instance of the class being tested, complete with its mocked dependencies.
116
97
-`unitRef` is a reference that allows you to access the mocked dependencies.
117
98
118
99
#### Testing `CatsApiService` with `TestingModule`
119
100
120
-
**Example: Using HttpModule and Nock**
121
-
122
-
For `CatsApiService`, we want to verify that the `HttpModule` is correctly imported and configured in the `CatsModule`
123
-
host module. This includes ensuring that the base URL (and other configurations) for `Axios` is set correctly.
101
+
For `CatsApiService`, we want to ensure that the `HttpModule` is properly imported and configured in the `CatsModule` host module. This includes verifying that the base URL (and other configurations) for `Axios` is set correctly.
124
102
125
-
For this case we won't use Suites, rather we'll use Nest's `TestingModule` to test the real configuration of `HttpModule`.
126
-
We'll use `nock` to mock HTTP requests without mocking the `HttpClient` in this case:
103
+
In this case, we won’t use Suites; instead, we’ll use Nest’s `TestingModule` to test the actual configuration of `HttpModule`. We’ll utilize `nock` to mock HTTP requests without mocking the `HttpClient` in this scenario.
127
104
128
105
```typescript
129
106
@@filename(cats-api.service)
@@ -178,8 +155,6 @@ describe('Cats Api Service Integration Test', () => {
178
155
179
156
#### Sociable Testing Example
180
157
181
-
**Example: Testing `CatsService` with Mocked Dependencies**
182
-
183
158
Next, let's test `CatsService`, which depends on `CatsApiService` and `CatsDAL`. We'll mock `CatsApiService` and
184
159
expose `CatsDAL`.
185
160
@@ -197,6 +172,8 @@ export class CatsDAL {
197
172
}
198
173
```
199
174
175
+
Next up, we have the `CatsService`, which depends on `CatsApiService` and `CatsDAL`:
176
+
200
177
```typescript
201
178
@@filename(cats.service)
202
179
@Injectable()
@@ -213,6 +190,8 @@ export class CatsService {
213
190
}
214
191
```
215
192
193
+
And now, let's test `CatsService` using sociable testing with Suites:
194
+
216
195
```typescript
217
196
@@filename(cats.service.spec)
218
197
import { TestBed, Mocked } from'@suites/unit';
@@ -247,50 +226,29 @@ describe('Cats Service Sociable Unit Test', () => {
247
226
});
248
227
```
249
228
250
-
**Explanation**
251
-
252
-
In this example, we use the `.sociable()` method to set up the test environment.
253
-
We used the `.expose()` method to expose `CatsDAL` to real interactions, while mocking `CatsApiService` with the
254
-
`.mock()` method. The `.final()` method defines fixed behavior for `CatsApiService`, ensuring consistent behavior across
255
-
tests.
229
+
In this example, we use the `.sociable()` method to set up the test environment. We utilize the `.expose()` method to allow real interactions with `CatsDAL`, while mocking `CatsApiService` with the `.mock()` method. The `.final()` method establishes fixed behavior for `CatsApiService`, ensuring consistent outcomes across tests.
256
230
257
-
This approach focuses on testing `CatsService` with real interactions with `CatsDAL`, which involves handling `Prisma`.
258
-
Suites will use `CatsDAL` as is, and only its dependencies will be mocked, e.g., `Prisma` in that case.
231
+
This approach emphasizes testing `CatsService` with genuine interactions with `CatsDAL`, which involves handling `Prisma`. Suites will use `CatsDAL` as is, and only its dependencies, like `Prisma`, will be mocked in this case.
259
232
260
-
**It's important to clarify that this approach is for verifying behavior only**, and it's different from loading the full testing module.
261
-
Sociable tests are useful for verifying the behavior of units in isolation from their direct dependencies, when you want to focus on the
262
-
behavior and interactions of units.
233
+
It's important to note that this approach is **solely for verifying behavior** and differs from loading the entire testing module. Sociable tests are valuable for confirming the behavior of units in isolation from their direct dependencies, especially when you want to focus on the behavior and interactions of units.
263
234
264
235
#### Integration Testing and Database
265
236
266
-
For `CatsDAL`, it is possible to test against a real database like SQLite or PostgreSQL (e.g., using Docker Compose).
267
-
However, for this example, we mock `Prisma` and focus on sociable testing. The reason we mock `Prisma` here is to avoid
268
-
I/O operations and focus on the behavior of `CatsService` in isolation, but you can also test it with real I/O operations
269
-
and a real database.
237
+
For `CatsDAL`, it's possible to test against a real database such as SQLite or PostgreSQL (for instance, using Docker Compose). However, for this example, we will mock `Prisma` and focus on sociable testing. The reason for mocking `Prisma` is to avoid I/O operations and concentrate on the behavior of `CatsService` in isolation. That said, you can also conduct tests with real I/O operations and a live database.
270
238
271
-
#### Sociable Unit Test, Integration Tests and Mocking
239
+
#### Sociable Unit Tests, Integration Tests, and Mocking
272
240
273
-
-**Sociable Unit Tests**: Focus on testing the interactions and behavior between units while mocking deeper dependencies.
274
-
In this example, we mock `Prisma` and expose `CatsDAL`.
241
+
- Sociable Unit Tests: These focus on testing the interactions and behaviors between units while mocking their deeper dependencies. In this example, we mock `Prisma` and expose `CatsDAL`.
275
242
276
-
-**Integration Tests**: Involve real I/O operations and fully configured DI. Testing `CatsApiService` with `HttpModule`
277
-
and `nock` is an integration test, as it verifies the real configuration and interaction of `HttpClient`. In this kind of
278
-
test, we will use Nest's `TestingModule` to load the actual module configuration.
243
+
- Integration Tests: These involve real I/O operations and a fully configured dependency injection (DI) setup. Testing `CatsApiService` with `HttpModule` and `nock` is considered an integration test, as it verifies the real configuration and interactions of `HttpClient`. In this scenario, we will use Nest's `TestingModule` to load the actual module configuration.
279
244
280
-
**Be careful when using mocks.** Ensure to test I/O operations and DI configurations (when HTTP or database interactions are
281
-
involved, for example). After verifying these components with integration tests, you can safely mock them for sociable unit
282
-
tests to focus on behavior and interactions. Suites sociable tests focus on verifying the behavior of units in isolation from
283
-
their direct dependencies, while integration tests ensure that the overall system configuration and I/O operations are
284
-
functioning correctly.
245
+
**Exercise caution when using mocks.** Be sure to test I/O operations and DI configurations (especially when HTTP or database interactions are involved). After validating these components with integration tests, you can confidently mock them for sociable unit tests to focus on behavior and interactions. Suites sociable tests are geared towards verifying the behavior of units in isolation from their direct dependencies, while integration tests ensure that the overall system configuration and I/O operations function correctly.
285
246
286
247
#### Testing IoC Container Registration
287
248
288
-
It's crucial to ensure that your DI container is correctly configured to avoid runtime errors. This involves verifying
289
-
that all providers, services, and modules are registered and injected correctly. Testing the DI container configuration
290
-
helps catch misconfigurations early and prevents issues that might only surface at runtime.
249
+
It's essential to verify that your DI container is properly configured to prevent runtime errors. This includes ensuring that all providers, services, and modules are registered and injected correctly. Testing the DI container configuration helps catch misconfigurations early, preventing issues that might only arise at runtime.
291
250
292
-
To ensure that the IoC container is correctly configured, let's create an integration test that loads the actual module
293
-
configuration and verify that all providers are correctly registered and injected:
251
+
To confirm that the IoC container is set up correctly, let's create an integration test that loads the actual module configuration and verifies that all providers are registered and injected properly.
0 commit comments