Unit tests for logic
๐ฏYou'll be able to
Write unit tests for logic such as money formatting, including edge cases.
๐ The everyday picture
Before a big wedding feast, the cook tastes the masala on its own. If the spice blend is wrong, it's easier to catch now than after it's in fifty dishes.
๐What it really is
- Keep tricky logic in plain functions, separate from components, so it's easy to test:
cartTotal(items, offers, deliveryFee). - A unit test with Vitest or Jest:
import { cartTotalPaise } from './cart';
test('applies free delivery at โน499 and above', () => {
const items = [{ pricePaise: 25000, qty: 2 }]; // โน500
expect(cartTotalPaise(items, { deliveryPaise: 3000 })).toBe(50000);
});
- Each test has three parts: arrange (set up data), act (call the function), assert (check the result).
- Cover edge cases: empty cart, exactly on a threshold, just below it, large quantities, rounding.
- Use table-driven tests (
test.each) for many similar cases. - Work in paise (whole numbers) to avoid floating-point surprises (
0.1 + 0.2isn't exactly0.3). - When a bug is reported, first write a test that reproduces it, then fix the code so the test passes.
๐A worked example
Kirana's free-delivery rule: "Free delivery on orders of โน499 or more; otherwise โน30."
| Cart value | Expected total | First result |
|---|---|---|
| โน0 (empty) | โน0 (no delivery fee on empty cart) | โน30 โ |
| โน498.99 | โน528.99 | โ |
| โน499.00 | โน499.00 | โน529.00 โ (used > instead of >=) |
| โน1,200 | โน1,200 | โ |
Two bugs were found by edge-case tests before any customer saw them.
๐Where it's used
- Prices, taxes, discounts and fees.
- Validation: pin codes, phone numbers, dates.
- Formatting: rupees, dates in IST, plurals.
๐Case scenario
A customer reports being charged a delivery fee on a โน499 order, though the banner says free delivery from โน499. You write a test for
exactly โน499, see it fail, change > to >=, and keep the test so the bug can't quietly return.
๐ฑ๏ธTry it
Move your Kirana cart calculation into a plain function. Write at least eight tests covering empty cart, thresholds, offers and large
quantities, using test.each for similar cases.
โ ๏ธCommon mistakes
- Testing only the happy path. Sign: zero, negative or large amounts break in production. Fix: add edge cases.
- Using floats for money. Sign: โน0.1 + โน0.2 isn't โน0.3. Fix: store paise as whole numbers and format at the end.
๐ ๏ธFor your project
lib/money.ts in the starter is broken on purpose; tests/unit/money.test.ts has 8 tests that pass once you fix it.
โ Quick check
What are the three parts of a unit test?
Show the answer
Arrange the data, act by calling the code, assert the result.
What should you do first when a bug is reported?
Show the answer
Write a test that reproduces it, then fix the code until the test passes.
