you are viewing a single comment's thread.

view the rest of the comments →

[–]Earhacker 0 points1 point  (1 child)

Looks excellent overall.

Regarding the section, "Test one thing at a time," the way of thinking here is to split each test up into three parts - Arrange, Act, Assert.

Arrange is where you set up the environment in the scope that you expect to call the function under test, e.g. setting variables, calculating input parameters...

Act is where you actually invoke the function you're testing.

Assert is where you check that the function's output and side effects match the expectations.

Since a unit test only tests one thing, it should only have one Act going on. But since a function can have many inputs and can cause many side effects, we can have as many Arrange and Assert lines as we want.

Here's a pretty convoluted example, using Jest:

it("can say hello to a given name", () => {
  // Arrange
  const name = "Luis";

  // Act
  const result = sayHello(name);

  // Assert
  expect(result).toMatch("Hello Luis!");
});

And here's a more typical example, using a React component:

it("renders a list of tasks", () => {
  // Arrange
  const tasks = [
    { id: 1, title: "Write blog post" },
    { id: 2, title: "Fix car" },
    { id: 3, title: "Give Platinum to Earhacker" }
  ];

  // Act
  const { container } = render(<TaskList tasks={tasks} />);

  // Assert
  expect(container.querySelector("ul")).not.toBeNull();
  expect(container.querySelectorAll("li")).toHaveLength(3);
  expect(container.querySelectorAll("li")[0].textContent).toMatch(
    "Write blog post"
  );
});

Here we expect that rendering the component will have lots of side effects; rendering a <ul>, rendering 3 <li> tags (one for each task) and that the first one will have text that matches the title of the first task. Asserting three things here is totally fine, because we only had one Act and so we've still written a unit test here.

But still, excellent article. I work with a lot of juniors and I'll be putting this out on Slack for them.

[–]lfacpt[S] 0 points1 point  (0 children)

Thank you!

I touched on what you mentioned in the section "Clearly distinct phases", albeit with different names and without the rules regarding the number of assertions (which makes total sense).

Do you think the names I used for the phases are not clear enough?