New BP: Test-middlewares

This commit is contained in:
Yoni
2020-02-26 20:30:03 +02:00
parent 7ea0b0fc6b
commit 7424f0cf99
2 changed files with 62 additions and 27 deletions

View File

@ -9,7 +9,7 @@
<br/>
<div align="center">
<img src="https://img.shields.io/badge/⚙%20Item%20count%20-%2085%20Best%20Practices-blue.svg" alt="85 items"> <img src="https://img.shields.io/badge/%F0%9F%93%85%20Last%20update%20-%20November%2012%202019-green.svg" alt="Last update: Oct 12, 2019"> <img src="https://img.shields.io/badge/ %E2%9C%94%20Updated%20For%20Version%20-%20Node%2012.12.0-brightgreen.svg" alt="Updated for Node 12.12.0">
<img src="https://img.shields.io/badge/⚙%20Item%20count%20-%2086%20Best%20Practices-blue.svg" alt="86 items"> <img src="https://img.shields.io/badge/%F0%9F%93%85%20Last%20update%20-%20March%2012%202020-green.svg" alt="Last update: March, 2020"> <img src="https://img.shields.io/badge/ %E2%9C%94%20Updated%20For%20Version%20-%20Node%2012.12.0-brightgreen.svg" alt="Updated for Node 13.1.0">
</div>
<br/>
@ -49,7 +49,7 @@ Read in a different language: [![CN](/assets/flags/CN.png)**CN**](/README.chines
1. [Project Structure Practices (5)](#1-project-structure-practices)
2. [Error Handling Practices (11) ](#2-error-handling-practices)
3. [Code Style Practices (12) ](#3-code-style-practices)
4. [Testing And Overall Quality Practices (12) ](#4-testing-and-overall-quality-practices)
4. [Testing And Overall Quality Practices (13) ](#4-testing-and-overall-quality-practices)
5. [Going To Production Practices (18) ](#5-going-to-production-practices)
6. [Security Practices (25)](#6-security-best-practices)
7. [Performance Practices (2) (Work In Progress ✍️)](#7-draft-performance-best-practices)
@ -257,8 +257,7 @@ function someFunction() {
}
// Avoid
function someFunction()
{
function someFunction() {
// code block
}
```
@ -335,11 +334,11 @@ class SomeClassExample {}
// for const names we use the const keyword and lowerCamelCase
const config = {
key: 'value'
key: "value"
};
// for variables and functions names we use lowerCamelCase
let someVariableExample = 'value';
let someVariableExample = "value";
function doSomething() {}
```
@ -373,12 +372,12 @@ function doSomething() {}
```javascript
// Do
module.exports.SMSProvider = require('./SMSProvider');
module.exports.SMSNumberResolver = require('./SMSNumberResolver');
module.exports.SMSProvider = require("./SMSProvider");
module.exports.SMSNumberResolver = require("./SMSNumberResolver");
// Avoid
module.exports.SMSProvider = require('./SMSProvider/SMSProvider.js');
module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolver.js');
module.exports.SMSProvider = require("./SMSProvider/SMSProvider.js");
module.exports.SMSNumberResolver = require("./SMSNumberResolver/SMSNumberResolver.js");
```
<br/><br/>
@ -392,18 +391,18 @@ module.exports.SMSNumberResolver = require('./SMSNumberResolver/SMSNumberResolve
### 3.10 Code example
```javascript
'' == '0' // false
0 == '' // true
0 == '0' // true
"" == "0"; // false
0 == ""; // true
0 == "0"; // true
false == 'false' // false
false == '0' // true
false == "false"; // false
false == "0"; // true
false == undefined // false
false == null // false
null == undefined // true
false == undefined; // false
false == null; // false
null == undefined; // true
' \t\r\n ' == 0 // true
" \t\r\n " == 0; // true
```
All statements above will return false if used with `===`
@ -538,6 +537,14 @@ All statements above will return false if used with `===`
🔗 [**Read More: Choosing CI platform**](/sections/testingandquality/citools.md)
## ![✔] 4.13 Test your middlewares in isolation
**TL;DR:** When a middleware holds some immense logic that spans many request, it worth testing it in isolation without waking up the entire web framework. This can be easily achieved by stubbing and spying on the {req, res, next} objects
**Otherwise:** A bug in Express middleware === a bug in all or most requests
🔗 [**Read More: Choosing CI platform**](/sections/testingandquality/test-middlewares.md)
<br/><br/><br/>
<p align="right"><a href="#table-of-contents">⬆ Return to top</a></p>
@ -1042,11 +1049,10 @@ All statements above will return false if used with `===`
<br /><br /><br />
## ![✔] 7.2. Prefer native JS methods over user-land utils like Lodash
**TL;DR:** It's often more penalising to use utility libraries like `lodash` and `underscore` over native methods as it leads to unneeded dependencies and slower performance.
Bear in mind that with the introduction of the new V8 engine alongside the new ES standards, native methods were improved in such a way that it's now about 50% more performant than utility libraries.
**TL;DR:** It's often more penalising to use utility libraries like `lodash` and `underscore` over native methods as it leads to unneeded dependencies and slower performance.
Bear in mind that with the introduction of the new V8 engine alongside the new ES standards, native methods were improved in such a way that it's now about 50% more performant than utility libraries.
**Otherwise:** You'll have to maintain less performant projects where you could have simply used what was **already** available or dealt with a few more lines in exchange of a few more files.
@ -1054,7 +1060,6 @@ All statements above will return false if used with `===`
<br/><br/><br/>
# Milestones
To maintain this guide and keep it up to date, we are constantly updating and improving the guidelines and best practices with the help of the community. You can follow our [milestones](https://github.com/i0natan/nodebestpractices/milestones) and join the working groups if you want to contribute to this project
@ -1132,14 +1137,14 @@ Thank you to all our collaborators! 🙏
Our collaborators are members who are contributing to the repository on a regular basis, through suggesting new best practices, triaging issues, reviewing pull requests and more. If you are interested in helping us guide thousands of people to craft better Node.js applications, please read our [contributor guidelines](/.operations/CONTRIBUTING.md) 🎉
| <a href="https://github.com/idori" target="_blank"><img src="assets/images/members/ido.png" width="75" height="75"></a> | <a href="https://github.com/TheHollidayInn" target="_blank"><img src="assets/images/members/keith.png" width="75" height="75"></a> |
| :--: | :--: |
| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
| :---------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: |
| [Ido Richter (Founder)](https://github.com/idori) | [Keith Holliday](https://github.com/TheHollidayInn) |
### Past collaborators
| <a href="https://github.com/refack" target="_blank"><img src="assets/images/members/refael.png" width="50" height="50"></a> |
| :--: |
| [Refael Ackermann](https://github.com/refack) |
| :-------------------------------------------------------------------------------------------------------------------------: |
| [Refael Ackermann](https://github.com/refack) |
<br/>

View File

@ -0,0 +1,30 @@
# Test your middlewares in isolation
<br/><br/>
### One Paragraph Explainer
Many avoid Middleware testing because they represent a small portion of the system and require a live Express server. Both reasons are wrongMiddlewares are small but affect all or most of the requests and can be tested easily as pure functions that get {req,res} JS objects. To test a middleware function one should just invoke it and spy ([using Sinon for example](https://www.npmjs.com/package/sinon)) on the interaction with the {req,res} objects to ensure the function performed the right action. The library [node-mock-http](https://www.npmjs.com/package/node-mocks-http) takes it even further and factors the {req,res} objects along with spying on their behavior. For example, it can assert whether the http status that was set on the res object matches the expectation (See example below)
<br/><br/>
### Code example: Testing middleware in isolation without issuing network calls and waking-up the entire web framework
```javascript
//the middleware we want to test
const unitUnderTest = require('./middleware')
const httpMocks = require('node-mocks-http');
//Jest syntax, equivelant to describe() & it() in Mocha
test('A request without authentication header, should return http status 403', () => {
const request = httpMocks.createRequest({
method: 'GET',
url: '/user/42',
headers: {
authentication: ''
}
});
const response = httpMocks.createResponse();
unitUnderTest(request, response);
expect(response.statusCode).toBe(403);
});
```