Skip to content

Latest commit

 

History

History
89 lines (68 loc) · 3.83 KB

types-or-tests.md

File metadata and controls

89 lines (68 loc) · 3.83 KB

Item 77: Understand the Relationship Between Type Checking and Unit Testing

Things to Remember

  • Type checking and unit testing are different, complementary techniques for demonstrating program correctness. You want both.
  • Unit tests demonstrate correct behavior on particular inputs, while type checking eliminates whole classes of incorrect behaviors.
  • Rely on the type checker to check types. Write unit tests for behaviors that can't be checked with types.
  • Avoid testing inputs that would be type errors unless there are concerns about security or data corruption.

Code Samples

test('add', () => {
  expect(add(0, 0)).toEqual(0);
  expect(add(123, 456)).toEqual(579);
  expect(add(-100, 90)).toEqual(-10);
});

💻 playground


function add(a: number, b: number): number {
  if (isNaN(a) || isNaN(b)) {
    return 'Not a number!';
    // ~~~ Type 'string' is not assignable to type 'number'.
  }
  return (a|0) + (b|0);
}

💻 playground


function add(a: number, b: number): number {
  return a - b; // oops!
}

💻 playground


test('out-of-domain add', () => {
  expect(add(null, null)).toEqual(0);
  //         ~~~~ Type 'null' is not assignable to parameter of type 'number'.
  expect(add(null, 12)).toEqual(12);
  //         ~~~~ Type 'null' is not assignable to parameter of type 'number'.
  expect(add(undefined, null)).toBe(NaN);
  //         ~~~~~~~~~ Type 'undefined' is not assignable to parameter of ...
  expect(add('ab', 'cd')).toEqual('abcd');
  //         ~~~~ Type 'string' is not assignable to parameter of type 'number'.
});

💻 playground


interface User {
  id: string;
  name: string;
  memberSince: string;
}

declare function updateUserById(
  id: string,
  update: Partial<Omit<User, 'id'>> & {id?: never}
): Promise<User>;

💻 playground


test('invalid update', () => {
  // @ts-expect-error Can't call updateUserById to update an ID.
  expect(() => updateUserById('123', {id: '234'})).toReject();
});

💻 playground