Testing with Jest
Jest is one of the most popular testing suites for Javascript and can be used for unit, component, and integration testing. Jest allows you to run through various aspects of your code while verifying that the results are what you expect.
The setup:
npm install --save-dev jest
Jest will automatically run any file that:
- is named with a .test.js extension OR
- is inside directory named ‘__tests__’
In order to run your tests, you’ll need to import your code modules into the test file(s) so that they can be accessed by the tests:
//sayName.jsfunction sayName(name){
return `My name is ${name}`;
}module.exports = sayName;
// sayName.test.jsconst { test, expect, describe } = require('@jest/globals');const sayName = require(‘./sayName’)
Once your modules are imported you can write and run tests using Jest’s methods.
describe() — creates a block to group related tests.
test() — is used to actual define a test
describe('My suite of name tests', () => {
test.only('that it says a greeting with the name', () => {
expect(sayName('Rick')).toBe('My name is Rick');
});
});
it() is an alias of test(). The only difference is how an error is phrased:it(‘says a name’, () => {
vs.
test(‘that it says a name’, () => {
expect() takes the name of the function being tested as an argument, and then requires a matcher (the expected outcome).
Different matchers are used to test in different ways:
toBe() — exact equality
toEqual() — recursively checks every field of an object or array
not.any_matcher() — reverses the logic
toBeTruthy matches anything that an if statement treats as true
toBeFalsy matches anything that an if statement treats as false
Number specific:
toBeGreaterThan()
toBeGreaterThanOrEqual()
toBeLessThan()
toBeLessThanOrEqual()
Strings:
toMatch — check against a regular expression (regex)
Arrays:
toContain() — contains a substring
You can add .only to test or describe to limit the tests that are run.
test.only(…
Running tests with the — coverage flag will give you an indication of what lines of code are not being tested by your tests. So if our original sayName function checked for an empty string:
function sayName(name){
if(!name){
return 'No name inputted.'
}
return `My name is ${name}`;
}
And we run the test with the coverage flag: test --coverage
we see the following in addition to our output:
The Uncovered Line is our untested line of code that checks for the empty string. Adding a second test returns us to 100% coverage:
test('an empty name', () => {
expect(sayName('')).toBe('No name entered');
});