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: docs/backend-web-development/express-middleware.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,7 @@ You could also imagine that it is a factory. For the request "assembly line", th
15
15
The request object, response object and the `next` function are passed to each middleware function. To move on to the `next` function to be run in the stack (could be a middleware function or handler function), the `next` function needs to be called.
16
16
17
17
```js
18
-
app.use(function(req, res, next) {
18
+
app.use((req, res, next)=> {
19
19
console.log("Method: "+req.method);
20
20
console.log("Path: "+req.url);
21
21
next();
@@ -75,7 +75,7 @@ Refer to the script: [Express.js playground: middleware_example_1](https://githu
75
75
Add a middleware function that will be called for all routes. It has no mount path.
76
76
77
77
```js
78
-
app.use(function(req, res, next) {
78
+
app.use((req, res, next)=> {
79
79
console.log("common middleware function was called!");
Copy file name to clipboardExpand all lines: docs/backend-web-development/express-testing.md
+72-38Lines changed: 72 additions & 38 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,17 +22,17 @@ The type of tests we are going to write is called integration test.
22
22
23
23
Integration tests, as the name suggests, tests that the different layers of your application (e.g. app, router, request handlers, any middleware, models and database) works as expected when integrated together.
24
24
25
-
In contrast, there is another type of tests, called Unit Test, which focus on testing a module/class/function works alone.
25
+
In contrast, there is another type of tests, called Unit Test, which focus on testing a module/class/function works alone. For example, react testing library is often used to unit test a single React component.
26
26
27
27
## Tests for API
28
28
29
29
To verify that your API works as expected, usually you need to send some requests to a running instance of your application, and check the responses. This can be done manually using tools like Postman or Insomnia, but we prefer to automate those tests.
30
30
31
31
To automate those tests, the tests need to act as API consumers, issuing requests and verifying responses.
32
32
33
-
###Using Jest as a testing framework
33
+
## Using Jest as a testing framework for testing our API
34
34
35
-
####Filename Conventions for Jest
35
+
### Filename Conventions for Jest
36
36
37
37
Jest will look for test files at:
38
38
@@ -45,26 +45,38 @@ It is recommended to put the test files next to the code they are testing so tha
45
45
46
46
Read more about this in the [Jest documentation](https://jestjs.io/docs/en/configuration#testregex-string--arraystring).
47
47
48
-
####Asynchronous tests with Jest
48
+
### Asynchronous tests with Jest
49
49
50
50
We will like to send requests to test our API. Requests are asynchronous, therefore we need to have asynchronous tests.
51
51
52
52
How can we do this with Jest?
53
53
54
54
- Add the `async` keyword
55
-
- Call `done` when you’re done with your tests
55
+
- Call `done` when you’re done with your tests if you want to tell Jest exactly where to end the test (optional)
56
+
57
+
`done` is a callback passed by Jest. Jest will wait until the done callback is called before finishing the test. Read more about it in the [Jest documentation](https://jestjs.io/docs/en/asynchronous#callbacks).
58
+
59
+
```js
60
+
it("Async test should do nothing", async () => {
61
+
// Do async operations here
62
+
});
63
+
```
64
+
65
+
using the done callback is optional
56
66
57
67
```js
58
-
it("Async test should do nothing", asyncdone=> {
68
+
it("Async test should do nothing", async(done)=> {
59
69
// Do async operations here
60
70
done();
61
71
});
62
72
```
63
73
64
-
###SuperTest
74
+
## SuperTest
65
75
66
76
Previously, we mentioned that we will like to send requests to test our API. You can use libraries like [SuperTest](https://github.com/visionmedia/supertest).
67
77
78
+
SuperTest wraps around SuperAgent, which is another API for creating HTTP requests / making calls to other APIs.
79
+
68
80
### Installation
69
81
70
82
Install SuperTest and save it to your package.json file as a development dependency:
@@ -73,18 +85,18 @@ Install SuperTest and save it to your package.json file as a development depende
73
85
npm install supertest --save-dev
74
86
```
75
87
76
-
###Testing with Jest and SuperTest
88
+
## Testing with Jest and SuperTest
77
89
78
90
SuperTest works without any framework but in our case we will use it along with Jest, since we are already using Jest as our testing framework.
79
91
80
-
####Refactoring for tests
92
+
### Refactoring for tests
81
93
82
94
Before we can start testing with SuperTest, we need to refactor our code to allow our server to be started by SuperTest for each of the tests.
83
95
84
96
Currently, our app looks like this in many of the examples where the routes exist in the same file as the server.
85
97
86
98
```js
87
-
//testing_example_1.js
99
+
//app.js
88
100
app.get("/", (req, res) => {
89
101
res.send("Welcome to my homepage");
90
102
});
@@ -101,45 +113,44 @@ This doesn’t work when creating tests because it starts listening to one port.
101
113
To solve this problem, you need to `export` the app without listening to it. Replace the `app.listen` code with `module.exports = app;`.
102
114
103
115
```js
104
-
//testing_example_1.js
116
+
//app.js
105
117
module.exports= app;
106
118
```
107
119
108
120
Now how do we run the server for development or production purposes? (not testing)
109
121
110
-
Normally when we are exporting the app like above, we do this in a file called **app.js**. (for this example, we shall just use testing_example_1.js)
122
+
Normally when we are exporting the app like above, we do this in a file called **app.js**.
111
123
112
124
We create a new file called **index.js** to start the server and make the server listen to port 3000.
113
-
(for this example, the file shall be called testing_example_1_index.js)
114
125
115
126
We `require` the previous file to import the app.
116
127
117
128
```js
118
-
//testing_example_1_index.js
119
-
constapp=require("./testing_example_1");
129
+
//index.js
130
+
constapp=require("./app");
120
131
constPORT=3000;
121
132
122
133
app.listen(PORT, () =>
123
134
console.log(`Server running at http://localhost:${PORT}`)
124
135
);
125
136
```
126
137
127
-
Run `node testing_example_1_index.js` again to start your server. Ensure that it still works.
138
+
Run `node index.js` again to start your server. Ensure that it still works.
128
139
129
-
####Writing tests
140
+
### Writing tests with SuperTest
130
141
131
142
First we will have to import SuperTest and our app.
expect(response.text).toEqual("Welcome to my homepage");
173
-
done();
174
182
});
175
183
});
176
184
```
@@ -180,17 +188,13 @@ Looks nicer! It passes with green.
180
188
What if we destructure the response to extract `text`?
181
189
182
190
```js
183
-
it("should respond correctly", asyncdone=> {
184
-
const { text } =awaitrequest(app)
185
-
.get("/")
186
-
.expect(200);
191
+
it("should respond correctly", async () => {
192
+
const { text } =awaitrequest(app).get("/").expect(200);
187
193
expect(text).toEqual("Welcome to my homepage");
188
-
done();
189
194
});
190
195
```
191
196
192
197
`request(app)` passes the app to SuperTest. We are then able to send GET, POST, PUT, PATCH and DELETE requests.
193
-
`done` is a callback passed by Jest. Jest will wait until the done callback is called before finishing the test. Read more about it in the [Jest documentation](https://jestjs.io/docs/en/asynchronous#callbacks).
194
198
195
199
How should we test this POST "/" route? We will need to POST some JSON and non-JSON content to the server, and then check its response.
196
200
@@ -212,22 +216,52 @@ Using SuperTest, we can easily send strings or JSON to the server:
212
216
213
217
```js
214
218
describe("POST /", () => {
215
-
it("should respond correctly when sending json", asyncdone=> {
219
+
it("should respond correctly when sending json", async()=> {
216
220
const { text } =awaitrequest(app)
217
221
.post("/")
218
222
.send({ thisIsJson:"json!" })
219
223
.expect(200);
220
224
expect(text).toEqual("Thanks for the JSON!");
221
-
done();
222
225
});
223
226
224
-
it("should respond with status 400 and correct string when sending non-json", asyncdone=> {
227
+
it("should respond with status 400 and correct string when sending non-json", async()=> {
After accessing the agent, you can use the agent directly.
247
+
248
+
For example,
249
+
250
+
```js
251
+
constagent=request.agent(app);
252
+
253
+
it("should respond correctly", async () => {
254
+
const { text } =awaitagent.get("/").expect(200);
255
+
expect(text).toEqual("Welcome to my homepage");
256
+
});
257
+
```
258
+
259
+
When should we use the agent directly?
260
+
261
+
There are some cases where we need to reuse the agent again. For example, we might need to persist cookies that were saved.
262
+
263
+
Check the [github page for supertest](https://github.com/visionmedia/supertest) for an example on how to access the agent in SuperTest and reuse the agent to persist a request and its cookies.
0 commit comments