In rspec you can do something like this:
let(:input) { 'foo' }
before_each do
setup_some_thing(input)
end
context 'when input is bar do
let(:input) { 'bar' }
it 'does something different' do
end
end
context 'when input is baz do
let(:input) { 'baz' }
it 'does something else different' do
end
end
This allows you to define a method call or instantiation of a large object as a sum of its smaller parts. You can then override those individual small parts inside different contexts. The idea being that you create a happy path before each test, and then specify deviations from the happy path within your context blocks.
Unfortunately, I can't seem to do this with Jest. I've tried the following:
beforeEach(() => {
let input = 'foo';
beforeEach(() => {
setupSomeThing(input);
});
describe('when input is bar', () => {
input = 'bar';
it('does something different', () => {
});
});
describe('when input is baz', () => {
input = 'baz';
it('does something different', () => {
});
});
});
Because jest executes every describe block before running any specific describe block, input is always 'baz'. Does anyone know a work around, or a way to get the rspec behavior?
Thanks in advance!
You can get similar behavior (albeit without lazy evaluation) using beforeAll.
beforeEach(() => {
let input = 'foo';
beforeEach(() => {
setupSomeThing(input);
});
describe('when input is bar', () => {
beforeAll(() => {
input = 'bar';
});
it('does something different', () => {
});
});
describe('when input is baz', () => {
beforeAll(() => {
input = 'baz';
});
it('does something different', () => {
});
});
});
The best solutions I've found have been libraries like
https://github.com/stalniy/bdd-lazy-var
and
https://github.com/tatyshev/given2
If you don't want to introduce a dependency, you can get similar behavior (albeit without lazy evaluation) by doing something like this:
beforeEach(() => {
let input = 'foo';
beforeEach(() => {
setupSomeThing(input);
});
describe('when input is bar', () => {
beforeAll(() => {
input = 'bar';
});
it('does something different', () => {
});
});
describe('when input is baz', () => {
beforeAll(() => {
input = 'baz';
});
it('does something different', () => {
});
});
});
beforeAll
to set variables in a parent beforeEach
.Building on @Noah's own answer, I thought I would share our final solution with using this
as well.
describe( "Logging in", () => {
beforeEach( () => login( this.password ) ); // Steps are same for all so re-use but use different password.
describe( "when password is incorrect", () => {
beforeAll( () => this.password = "INCORRECT PASSWORD" );
it( "doesn't log in.", () => {
// Your assertion(s).
} );
} );
describe( "when password is correct", () => {
beforeAll( () => this.password = "CORRECT PASSWORD" );
it( "logs in successfully.", () => {
// Your assertion(s).
} );
} );
} );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With