In many cases you could just use a plain function instead of a beforeEach hook. In the below case it's both more clear and less code.
import test from 'ava';
const setup = () => {
doStuff();
return {
unicorn: fn('unicorn')
rainbow: fn('rainbow')
};
}
test('foo', t => {
const {unicorn, rainbow} = setup();
t.true(unicorn('foo'));
t.true(rainbow('foo'));
});
test('bar', t => {
const {unicorn, rainbow} = setup();
t.true(unicorn('bar'));
t.true(rainbow('bar'));
});
With beforeEach it would be:
import test from 'ava';
test.beforeEach(t => {
doStuff();
t.context = {
unicorn: fn('unicorn')
rainbow: fn('rainbow')
};
}
test('foo', t => {
const {unicorn, rainbow} = t.context;
t.true(unicorn('foo'));
t.true(rainbow('foo'));
});
test('bar', t => {
const {unicorn, rainbow} = t.context;
t.true(unicorn('bar'));
t.true(rainbow('bar'));
});
Still, there are benefits of beforeEach too. They're not mutually exclusive. beforeEach has benefits like supporting non-promise asynchronicity. Better output when a hook fails. Void hook usage doesn't require a call in each test. And more.
The real advantage of the setup function approach is that you could have more than one, and call them based on what you need in a particular test. (If you interact with the file system, perhaps you run a few tests using mock-fs, and then a few that use the real file system and a temp dir or something).
There is a (very small) performance benefit to not having any beforeEach or afterEach tests. It's not worth worrying about unless you are dealing with hundreds (maybe even thousands) of tests in a single file though.
I have come to prefer the setup() approach personally. It does not require others to be familiar with AVA's t.context, there is no magic.
Can I pick this up?
@JasonRitchie Of course. Go ahead :)