Reputation: 10035
I'm learning TDD from this article and the author talks about how Mocha's beforeEach
will run a code before each assertion for you. But I don't understand why you need to do that when you can just run the code in the describe scope.
describe('Test suite for UserComponent', () => {
beforeEach(() => {
// Prevent duplication
wrapper = shallow(<UserComponent
name={ 'Reign' }
age={ 26 } />);
});
it('UserComponent should exist', () => {
expect(wrapper).to.exist;
});
it('Correctly displays the user name and age in paragraphs wrapped under a parent div', () => {
expect(wrapper.type()).to.equal('div');
// more code...
});
});
But not using the beforeEach
would still work -
describe('Test suite for UserComponent', () => {
wrapper = shallow(<UserComponent
name={ 'Reign' }
age={ 26 } />);
it('UserComponent should exist', () => {
expect(wrapper).to.exist;
});
it('Correctly displays the user name and age in paragraphs wrapped under a parent div', () => {
expect(wrapper.type()).to.equal('div');
// more code...
});
});
Upvotes: 3
Views: 1293
Reputation: 151411
beforeEach
is executed before each test. This iteration is lost when the code is moved from beforeEach
to be directly inside the function passed to describe
. However, that's not all.
In some cases, code executed directly inside the function passed to describe
can perform the same task as a beforeEach
hook. For instance, if its function is to initialize a read-only structure that is local to the test in the describe
block, then you could skip the beforeEach
hook.
However, Mocha executes right away all the callbacks that are passed to describe
calls whereas a beforeEach
call registers the function passed to it for future execution, and it will be executed only if needed. If the initialization is expensive it is better to use a beforeEach
hook because if you make use of --grep
to select only some test, or use it.only
to run a single test, then Mocha will run the hook only if it pertains to the test it will actually run. If you have the initialization code in describe
, Mocha cannot skip it so you'll pay the initialization cost every time. However, if you are going to use a hook and the data is immutable, then before
is better than beforeEach
because it will run just once instead of before each test.
Then there are cases where running code in directly in the function passed to describe
simply won't work. Imagine in the following that sharedResource
is a resource that all tests need to use. It could be a third-party library that carries state, for instance. Some tests need it to be set to a certain state. Other tests need it to be in a different state. This does not work:
"use strict";
const assert = require('assert');
let sharedResource;
describe("in condition a", () => {
sharedResource = true;
it("sharedResource is true", () => assert(sharedResource));
});
describe("in condition b", () => {
sharedResource = false;
it("sharedResource is false", () => assert(!sharedResource));
});
The first test will fail because the execution order of the key statements is:
sharedResource = true;
sharedResource = false;
assert(sharedResource);
assert(!sharedResource);
The problem can be easily fixed by using beforeEach
. This runs fine:
"use strict";
const assert = require('assert');
let sharedResource;
describe("in condition a", () => {
beforeEach(() => {
sharedResource = true;
});
it("sharedResource is true", () => assert(sharedResource));
});
describe("in condition b", () => {
beforeEach(() => {
sharedResource = false;
});
it("sharedResource is false", () => assert(!sharedResource));
});
Upvotes: 3