Score 100% on the quiz to continue
Your first unit test
Write a test with describe, test, and expect, run it, and learn to read a failure.
A unit test checks one small piece of code, a unit, on its own: usually a function, called with some input, with its result compared against what a rule says it should be. No browser, no server, no database. That is why unit tests run in milliseconds, and why a failing one points straight at what broke.
In this lesson, you write your first unit test, for lateFee(), and learn the three things every Jest test is made of: a group, a test, and an expectation.
Commands overview 📖
require() the code under test
A test file is plain JavaScript. It starts by requiring the function it tests.
Syntax:
const { functionName } = require('./module-file')Example:
const { lateFee } = require('./fees')👨🏫 You never require Jest itself. When Jest runs a test file, it makesdescribe,test,expect, and the rest available as globals.
describe()
Groups related tests under a name. Groups can be nested, and the names add up in the output.
Syntax:
describe('<what is being tested>', () => {
// tests go here
})Example:
describe('lateFee', () => {
// tests for lateFee() go here
})test() (or it())
Defines one test: a name and a function that runs it. it is an alias for test, so it('charges...') and test('charges...') are the same thing. This course uses test.
Syntax:
test('<the behavior, as a sentence>', () => {
// call the code and check the result
})Example:
test('charges 25 cents for each day late', () => {
expect(lateFee(10)).toBe(250)
})👨🏫 Name a test after the behavior it checks, not after the function. "charges 25 cents for each day late" tells you what broke when it fails. "lateFee works" tells you nothing.
expect() and toBe()
expect(value) wraps the value you got, and a matcher compares it with the value you expected. toBe() is the simplest matcher: it passes when both are the same value (it uses Object.is, which is strict equality, ===, for numbers and strings).
Syntax:
expect(<received>).toBe(<expected>)Example:
expect(lateFee(0)).toBe(0)Running one file, or everything
Syntax:
npm test
npx jest <path-to-test-file>Example:
npx jest src/fees.test.jsWatch mode
--watch keeps Jest running and reruns the tests related to the files you change, every time you save. While it runs, press a to run all tests, f to run only the failed ones, p to filter by file name, t to filter by test name, and q to quit.
Syntax:
npx jest --watchExample:
npm test -- --watch👨🏫--watchrelies on git to know which files changed, which is why it works in your clone out of the box. The--innpm test -- --watchtells npm to pass the flag through to Jest instead of keeping it for itself.
Reading a failure
A test you have never seen fail might not be checking anything. So the first thing to learn is how a failure reads. Suppose a test expects 200 where the rule says 250:
FAIL src/fees.test.js
lateFee
✕ charges 25 cents for each day late (3 ms)
● lateFee › charges 25 cents for each day late
expect(received).toBe(expected) // Object.is equality
Expected: 200
Received: 250
5 |
6 | test('charges 25 cents for each day late', () => {
> 7 | expect(lateFee(10)).toBe(200)
| ^
8 | })Read it from the top:
FAILand the file name: which file has a failing test.lateFee › charges 25 cents for each day late: thedescribename and thetestname, joined. Good names make this line a sentence.ExpectedandReceived: what the test wanted, and what the code returned.- The code frame: the exact line of the failing assertion, with a caret under the matcher.
And then decide who is wrong. Here, the README says 25 cents a day, so 10 days is 250, and the test is wrong. Later in the course, it will be the other way around.
Suggested content 📚 and documentation links 🔗
Exercise 🎯
Create the file src/fees.test.js. Inside a describe('lateFee') block, write tests for these README rules, using values well inside each range:
- A book returned on time (
0days late) has no fee. - A book
10days late costs250cents (25 cents for every day late). - A book
20days late costs500cents.
Run npm test and watch all three pass. Then break one on purpose: change the expected value of the 10-day test to 200, run it again, and read the failure from top to bottom as described above. Put it back to 250.
Finally, start watch mode with npm test -- --watch, change and save the test file a couple of times, and watch the tests rerun on their own. Press q to quit.
👨🏫 Commit the new test file and push it.
Show the world what you learned 🌎
To show your professional network what you learned in this lesson, post the following on LinkedIn.
I am taking the "Unit Testing with Jest" course by @Walmyr Lima e Silva Filho at the @Talking About Testing School, and I just wrote my first unit tests with Jest, watched one fail on purpose, and learned to read the expected and received values and the code frame of a failure. #TalkingAboutTesting #TATSchool #UnitTestingWithJest #Jest #UnitTesting
👨🏫 Remember to tag me in your post. Here is my LinkedIn profile.
Quiz
A test fails with Expected: 200 and Received: 250 for lateFee(10). What should you do before changing anything?
Score 100% on the quiz to continue