Coderrob brand logo Coderrob

Hi, I'm Rob—programmer, Pluralsight author, software architect, emerging technologist, and lifelong learner.


Unit Testing: Rules and Best Practices


Fri, 21 Feb 2025

Rules to Follow

FIRST Principles

  1. Fast – Tests should run quickly to allow frequent execution.
  2. Independent – Tests must not depend on each other.
  3. Repeatable – A test should always yield the same result.
  4. Self-Checking – Tests should automatically verify correctness.
  5. Timely – Write tests before or alongside implementation.

Coverage & Quality

Self-Describing Tests

SEE Pattern (made this one up)

  1. Setup – Initialize inputs and dependencies.
  2. Execute – Run the function under test.
  3. Expect – Assert the expected outcome.

NOTE: I call it “SEE” because you see immediately what it did or didn’t do.

Frameworks & Tools

Things to Avoid

Test Bleeds

External Dependencies

Complex Test Logic

Behavioral Assertions Matter

Private/Internal Method Testing

Flaky Tests Are a No-Go

How to Structure Tests

describe("Math", () => {
  describe("add", () => {
    it("should return the sum of two numbers", () => {
      expect(Math.add(1, 2)).toBe(3);
    });
  });
});
Math (describe)
├── add (describe)
│   ├── (it) should return the sum of two numbers

Mocking Dependencies

// Setup
const mockLogger = { log: jest.fn() };
// Execute
new Service(mockLogger).execute();
// Expect
expect(mockLogger.log).toHaveBeenCalledTimes(1);
expect(mockLogger.log).toHaveBeenNthCalledWith(
  1,
  "dear diary... naming is hard"
);

Edge Cases Matter

it.each([
  { a: 0, b: 0, expected: 0 },
  { a: -1, b: -1, expected: -2 },
  { a: 1, b: Spanish.INQUISITION, expected: 0 },
  { a: Number.MAX_VALUE, b: 1, expected: Number.MAX_VALUE + 1 },
])("should return $expected when adding $a and $b", ({ a, b, expected }) =>
  expect(add(a, b)).toBe(expected)
);

Ensuring Quality & Maintainability

Automate Testing

Monitor & Improve Coverage

Refactor Tests as Code Evolves

Review Tests Like Production Code

By following these principles, unit tests will be reliable, efficient, and maintainable, elevating software quality and developer confidence.