When writing test expectations for functions that throw, we need a bit careful.

For example, consider this simple test:

test('function throws', () {
  expect(
    someFunctionThatThrows(),
    throwsStateError,
  );
});

In this case, the test will fail, because someFunctionThatThrows() is evaluated before the expect function is called.

This is equivalent to writing the test like this:

test('function throws', () {
  // if the function throws, the test will fail immediately
  final result = someFunctionThatThrows();
  // and this line will never be exectuted
  expect(
    result,
    throwsStateError,
  );
});

To fix this, we can pass an anonymous function as an argument to the expect method:

test('function throws', () {
  expect(
    // function argument, will be evaluated *inside* the expect function
    () => someFunctionThatThrows(),
    throwsStateError,
  );
});

Or even better, we can use a tear-off and pass someFunctionThatThrows directly as an argument (without calling it):

test('function throws', () {
  expect(
    someFunctionThatThrows,
    throwsStateError,
  );
});

This is safer, and more concise too! 👌

For more info about tear-offs, see this rule about effective Dart usage.

Happy coding!