This project experiments with an alternative to beforeEach
when testing.
This wraps it
, it.only
, and it.skip
to allow for 3 arguments:
- The title of your test
- An object or function that provide data to your test (more on that later)
- The test itself that receives data as its argument
it('accepts a setup function', generateMockUser, ({ user }) => {
// test your mock user here just like normal
});
For me, beforeEach
works fine for setup code that is very side effect oriented.
These are "fire and forget" functions such as stubbing out the network or resetting a mock.
I think beforeEach
starts to break down when we want to produce data that our tests will consume.
The pattern I've seen most results in a laundry list of let
declarations that are (re)assigned as
part of the beforeEach
callback.
let testUserId;
beforeEach(() => {
testUserId = 123;
});
With only a few items this isn't so bad, but as a test file starts to grow this can become hard to follow and maintain.
What would be nice is to have a function produce data that is fed to our test. This has a few benefits:
- We can use standard function composition to deal with complex setups.
- There's no longer a need for
let
variables since data is given to your test as local variables - Setup functions can easily be moved out of a test because they don't interact with local scope
- We can also define a teardown function associated to the setup to bundle them together.
This repo is a Proof of Concept to see what testing in this manner would look like.
There are a few examples:
- ./src/basics.test.js gives an overview of using this approach
- ./src/enzymeExamplePureSetup.test.js gives a more involved example using enzyme
- ./src/enzymeExamplePureSetupExternal.test.js shows how easy it is to move all of the setup outside of the test (if you wanted to do that).
- ./src/enzymeExampleClassic.test.js
shows the same example using
beforeEach
for comparison purposes. Obviously, there would be numerous ways to structure the example, but I tried to model it after patterns I have seen often in actual code.
You can run the tests via yarn test
.
The actual implementation is in ./src/setupTests.js and relies on wrapping the existing jest methods. I actually think this could work to some extent, but the intention of this repo is just to prove out the testing pattern as a whole. If the pattern seems viable then I think it would be awesome to see if Jest would consider supporting this first class in the code.