mardi 7 juillet 2020

In certain contexts, can we use multiple assertions in one unit test?

I’d like some advice on the use of multiple assertions in one test.

Some articles advise against multiple assertions in a test (I can understand why). But given my context, I’d welcome some help on if my approach is right.

For some context, I have a simple function sortUsersByAge(users), it accepts an array of user objects and returns a new array with the user objects sorted by their age property, in ascending order. No other side effects.

Here’s an example of the usage:

// Excuse the curly quotes, composing on an iPad

let users = [
  { name: “Bob”, age: 32 },
  { name: “Claire”, age: 19 },
  { name: “Jo”, age: 40 }
];

const sortedUsers = sortUsersByAge(users);

/*
sortedUsers: [
  { name: “Claire”, age: 19 },
  { name: “Bob”, age: 32 },
  { name: “Jo”, age: 40 }
]
*/

Within my tests I would look to assert that the returned array contains these user objects, sorted by age, in ascending order.

Here’s an example of how I’d test using multiple asserts:

// Extract of tests
// Excuse the curly quotes, composing on an iPad

it(“should sort the user objects by the age property, in ascending order”, () => {

  const users = [
    { name: “Bob”, age: 32 },
    { name: “Claire”, age: 19 },
    { name: “Jo”, age: 40 }
  ];

  const sortedUsers = sortUsersByAge(users);

  expect(sortedUsers[0].age).toBe(19); // Pass
  expect(sortedUsers[1].age).toBe(32); // Pass
  expect(sortedUsers[2].age).toBe(40); // Pass
});

I’d look to take this approach as I’m specifically asserting against the order of the objects based on the age property. Although to do so, I’m having to resort to using multiple assertions.

An alternative approach could be to replicate the returned array and use a single assertion to assert equal. As seen here:

// Extract of tests
// Excuse the curly quotes, composing on an iPad

it(“should sort the user objects by the age property, in ascending order”, () => {

  const users = [
    { name: “Bob”, age: 32 },
    { name: “Claire”, age: 19 },
    { name: “Jo”, age: 40 }
  ];

  const expected = [
    { name: “Claire”, age: 19 },
    { name: “Bob”, age: 32 },
    { name: “Jo”, age: 40 }
  ];

  const sortedUsers = sortUsersByAge(users);

  expect(sortedUsers).toEqual(expected); // Pass
});

Although the above approach aligns with the rule of “one assertion per test”. I believe I am now touching on testing the schema, not the specific age order. Also, errors and maintainability issues could be introduced.

Overall, I’m convinced the multiple assertions rule should not apply in this context. But I’d welcome some guidance on what the agreed approach is in these circumstances as much searching hasn’t given much clarity on the issue.

Thanks.

Aucun commentaire:

Enregistrer un commentaire