Write Functional Tests & Assertions

Today while addressing a bug in Amplify JS, I found a passing test that was broken:

expect(reject).toBeCalled()

It turns out, the implementation had a runtime error in it:

try {
  someUndefinedFunction()
} catch (error) {
  // ReferenceError: someUndefinedFunction is not defined
  reject(error)
}

But because the expect only tested that an error happened, we couldn’t differentiate between an expected vs. unexpected error.

Tests should be functional: given this input, I expect that output.

// This is OK for testing that a logic gate is called
expect(reject).toBeCalled()
// 🎉 This is *better* for enforcing API contracts
expect(reject).toBeCalledWith(expectedError)

Now, our application is more resilient to regressions with:

  1. The logic gate for calling reject.
  2. The type & shape of the error passed to reject.