Search code examples
javascriptunit-testingtestingjestjs

How to test that a function returned without doing anything


I'm writing a suite of Jest tests, and the following question came up. How can I test that a function simply returns if it receives an invalid argument? For example, I would like to test that the function changeAge below returns immediately if it receives a newAge or id that is not a whole number.

function changeAge (id, newAge) {
  const isWholeNumber = num => Number.isInteger(newAge) && newAge >= 0
  if (!isWholeNumber(id) || !isWholeNumber(newAge)) {
    return
  } 

  const person = getPerson(id)
  person.age = newAge
}

In this example, there's no way in the test to retrieve the person data to verify whether the age property was changed.


Solution

  • Your function is called changeAge. It's not called changeAgePerhaps 🙂.

    If the function can't do what it advertises, you should throw an error (or return a Result type that indicates success/error).

    Your caller just handed you crappy parameters. Why hide this from them when your validation fails?

    By swallowing the error and pretending everything is fine, you're storing up big trouble for your consumers. It's no longer clear if the call succeeded. Even if you can write a contrived test to ensure this is the case under idealized conditions, your consumers won't know (or care) to do this. You should just straight-up tell them "something has gone wrong".

    In a small codebase, you might be happy with this decision. In a large codebase, this kind of code will cause you some serious headaches.

    IMO It's time to reconsider whether this is really how you want to proceed.