jest-extended
jest-extended copied to clipboard
An inverse of Jest's `.toContain` matcher
The problem
I tutor a university course where we assess the correctness of students work using Jest. Sometimes, our assignment specs expect random behaviour, for example assigning a random colour to a new user's profile. Currently, our code to test this looks like:
// Allowed values are defined in the spec
const validColors = ['red', 'green', 'blue', 'purple', 'pink', 'yellow'];
// Expect that the user's profile colour is one of the valid options
expect(validColors).toContain(getUserProfile(userId).color);
As you can see, our expect statement is backwards: the expected value is passed as the actual value and the actual value is passed as the expected value. This causes Jest to give a very confusing error message.
Expected value: beige
Received array: ['red', 'green', 'blue', 'purple', 'pink', 'yellow']
I've seen this error message trip up students time and time again, and so believe there should be a dedicated matcher to improve the readability of errors in this case.
A proposed solution
A new matcher, perhaps named toBeContainedWithin which essentially behaves like the inverse of toContain.
// Allowed values are defined in the spec
const validColors = ['red', 'green', 'blue', 'purple', 'pink', 'yellow'];
// Expect that the user's profile colour is one of the valid options
expect(getUserProfile(userId).color).toBeContainedWithin(validColors);
This would produce much clearer error messages.
Expected one of: ['red', 'green', 'blue', 'purple', 'pink', 'yellow']
Received value: beige
Alternatives
A simple alternative is to just use an expression such as validColors.includes(getUserProfile(userId).color).toBe(true);. However, this would produce far less-descriptive error messages.
Expected value: true
Received value: false
This is a reasonable alternative without a dedicated matcher, but doesn't fully satisfy my desire to have our auto-marking system give detailed explanations of failing tests to students.