What is the difference between `before()` and `beforeEach()`?
javascript, mocha.js, unit-testing
Solution
`before()` is run once before all the tests in a `describe` `after()` is run once after all the tests in a `describe` `beforeEach()` is run before each test in a `describe` `afterEach()` is run after each test in a `describe`
Which one you want to use depends on your actual test.
Now, for the long explanation. If you run `mocha -R min` on this:
describe("top", function () {
before(function () {
console.log("top before");
});
after(function () {
console.log("top after");
});
beforeEach(function () {
console.log("top beforeEach");
});
afterEach(function () {
console.log("top afterEach");
});
it("test1", function () {
console.log("top test1");
});
describe("sublevel", function() {
before(function () {
console.log("sublevel before");
});
after(function () {
console.log("sublevel after");
});
beforeEach(function () {
console.log("sublevel beforeEach");
});
afterEach(function () {
console.log("sublevel afterEach");
});
it("test1", function () {
console.log("sublevel test1");
});
it("test2", function () {
console.log("sublevel test2");
});
});
it("test2", function () {
console.log("top test2");
});
});
You'll see something like (I've omitted the output that is not relevant):
top before
top beforeEach
top test1
top afterEach
top beforeEach
top test2
top afterEach
sublevel before
top beforeEach
sublevel beforeEach
sublevel test1
sublevel afterEach
top afterEach
top beforeEach
sublevel beforeEach
sublevel test2
sublevel afterEach
top afterEach
sublevel after
top after
The thing that may be surprising if you look at what executes before and after each of the tests at the sublevel is that both the `beforeEach` callbacks at the top level and at the sublevel are called. Same thing for the `afterEach`.
Some are also surprised by the sequence `sublevel before`, `top beforeEach`, `sublevel beforeEach`. They think that all the hooks in an outer scope should execute before all the hooks in an inner scope, so they expect the sequence: `top beforeEach`, `sublevel before`, `sublevel beforeEach`. However, the order in which Mocha executes the hooks makes complete sense: a `before` hook is meant to set the stage for a group of tests, whereas a `beforeEach` test is for each individual tests. When Mocha executes a test, all the `before` and the `beforeEach` hooks that were set in the `describe` that contains it, and all the ancestors of that `describe` apply to the test. Mocha will execute each `before` hook from the outermost scope to the innermost, and all `beforeEach` hook from the outermost scope to the innermost. However, all `before` hooks that apply are executed before any `beforeEach` hook. This explains the order above: `sublevel before` executes before `top beforeEach` because it is a `before` hook. And with `after` and `afterEach`, the same logic applies but the the order is reversed: all `afterEach` hooks that apply are executed before any `after` hook.
Also notice that Mocha does not care about how I ordered my `it` calls relative to the `describe` call in the top level `describe`. It executes `top test1`, `top test2` and then the sublevel tests, even though the order I gave was `top test1`, then the sublevel tests and then `top test2`.
What you want to use among `before`, `beforeEach`, etc. really depends on the specifics of your tests. If you need to setup a mock object or data structure and this object or structure can be reused by all the tests in a single `describe`, you can use `before` to set it up, and `after` to tear it down. This could be the case if you are doing read-only tests on the structure. If all your tests only read it, then there is no need to create it over and over. If each test in your `describe` needs a new copy of the structure because each test is modifying the structure then you should use `beforeEach` to create the structure anew for each test and then `afterEach` if you need to tear it down cleanly. Doing this ensures test isolation: each test starts from a known state and does not depend on the presence or absence of a previous test to succeed.
Problem
What specifically is the difference between Mocha's `before()` and `beforeEach()`? (Same question for `after()` and `afterEach()`.) I assume `before()` runs once per `describe()` block, and `beforeEach()` runs once per test (`it()` block). Is that true? And when would I choose to use one over the other?