Testing
Master automated testing to catch bugs before production. Learn unit tests, mocking, async testing, API testing, and test-driven development with Jest and Mocha.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Testing frameworks require Node.js. To practice:
What You'll Learn
Why Automated Testing?
Testing transforms "I think this works" into "I know this works." A solid test suite gives you confidence to refactor, fast feedback on bugs, and protection against regressions.
Jest Basics
Jest is all-in-one: test runner, assertion library, mocking, coverage, and watch mode built in. Perfect for React and modern JavaScript projects.
Mocha + Chai
Mocha is a minimal test runner paired with Chai for assertions. This combination gives you fine-grained control over your testing stack.
Testing Async Code
Real apps are full of async code: API calls, timers, database queries. Both Jest and Mocha handle async testing with async/await and Promises.
Mocking with Jest
Mocking isolates the code under test by replacing dependencies with controlled substitutes. Jest includes powerful mocking capabilities built-in.
💡 When to Mock: Mock external services (APIs, databases), slow operations, unpredictable values (random, time), and modules with side effects. Keep tests fast, isolated, and deterministic.
Sinon for Mocha
Sinon provides spies, stubs, and mocks for Mocha. It's the companion library that gives Mocha the same mocking power Jest has built-in.
Testing Timers
Test time-based logic like debounce, throttle, countdowns, and delays using fake timers. Control time programmatically for instant, reliable tests.
API Testing with Supertest
Test Express/Node.js APIs by making HTTP requests and asserting responses. Supertest makes API testing clean and expressive.
Test Coverage
Coverage reports show which lines, branches, and functions your tests execute. Use coverage thresholds to enforce testing standards.
Test-Driven Development (TDD)
TDD means writing tests before implementation. This drives better design and ensures every feature has test coverage from the start.
Testing Best Practices
Follow these patterns to write tests that are reliable, maintainable, and actually catch bugs instead of just passing.
Key Takeaways
Practice quiz
In Jest, which function groups related tests together?
- expect()
- mock()
- describe()
- assert()
Answer: describe(). describe() groups related tests; test()/it() define individual cases.
Which Jest matcher checks that a function throws an error?
- .toThrow()
- .toBe()
- .toEqual()
- .toContain()
Answer: .toThrow(). expect(() => fn()).toThrow() asserts that the function throws.
What is the PREFERRED way to test async code in the lesson?
- The done callback
- Synchronous loops
- setTimeout polling
- async/await
Answer: async/await. async/await is presented as the preferred, cleanest style for async tests.
What does jest.fn() create?
- A real API call
- A mock function you can assert calls on
- A new test file
- A coverage report
Answer: A mock function you can assert calls on. jest.fn() creates a mock function whose calls can be tracked and asserted.
What is the purpose of jest.useFakeTimers()?
- To control time so debounce/throttle/countdowns can be tested instantly
- To make tests slower
- To delete timers
- To mock fetch
Answer: To control time so debounce/throttle/countdowns can be tested instantly. Fake timers let you advance time programmatically for reliable time-based tests.
In Sinon, what is a 'spy' used for?
- Replacing a function entirely
- Throwing errors
- Tracking function calls without changing behavior
- Mocking the DOM
Answer: Tracking function calls without changing behavior. A spy records how a function was called while leaving its behavior intact.
Which library is used to test Express/Node.js APIs in the lesson?
- DOMPurify
- Supertest
- Chalk
- Webpack
Answer: Supertest. Supertest makes HTTP requests against an app and lets you assert on responses.
What does the 'Branches' coverage metric measure?
- Git branches tested
- The number of files
- Lines of comments
- The % of if/else paths tested
Answer: The % of if/else paths tested. Branch coverage is the percentage of conditional (if/else) paths exercised by tests.
What is the correct order of the TDD workflow?
- Code, then test, then ship
- Write a failing test, write minimum code to pass, then refactor
- Refactor, test, document
- Test only at the end
Answer: Write a failing test, write minimum code to pass, then refactor. TDD: write a failing test, make it pass with minimal code, then refactor while green.
Which testing best practice does the lesson recommend?
- Test private implementation details
- Put all assertions in one test
- Test observable behavior, not implementation
- Use names like test1
Answer: Test observable behavior, not implementation. Test behavior rather than internal/private details so tests survive refactors.