How Jest Reveals Test Smells
Unfortunately I discover very often when using jest that a lot of the things point me to smells in a test. Jest even encourages some of those instead of encouraging us to write better tests. I found some things over time, so I just collect them here.
Is there a blog post showing how all the features of jest can be prevented to be needed by better test writing practices?
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) May 6, 2020
Maybe I should write it.#javascript #testing
jest.mock
I just saw code that uses jest.mock and read https://t.co/JFpyTMojQn
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) May 13, 2020
I hear "let the tests drive you", I think "too much setup code".
I am trying to prevent to mock what I don't own.
I feel bad when I (rarely) test that the right parameter is passed to a stubbed function.
jest.fn
Check how many stubs/spies you can replace by noop-functions!
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) June 24, 2020
If you don't spy, don't use
- sinon.spy()
- jest.fn()
- ...
A noop-function does the job as well
- () => {}
or
- async () => {}
Don't make the #test more complicated than necessary!
jest.setSystemTime()
or jest.getRealSystemTime()
You are just about to use `jest.setSystemTime()` or `jest.getRealSystemTime()`?
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) December 7, 2020
Why not inject the function that you are actually trying to fake a value for and inject this dependency?#dependencyInjection#explicitCode
How?
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) December 7, 2020
// dont use:
const fn= () => {
x = new Date().toISOString();
}
// use:
const fn = (nowFn) => {
x = nowFn();
}
and you can control what `nowFn` is, does and returns in your test, because you inject it.#tdd #testing #jest #mocha#inject #dependencies
2/
You can also inject a default dependency (for production), if you like:
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) December 7, 2020
const defaultNowFn =
() => new Date().toISOString();
const fn =
(nowFn = defaultNowFn) => {
...
}
3/#javascript #jest #tested #code #parameterized
Reintroduce this
?
"You can also pass variables from this module to your test suites by assigning them to https://t.co/bpdtat1Io7 object – this will make them available in your test suites as global variables."https://t.co/xvNGQO0ywg
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) May 19, 2020
Wasn't the magic `this` one of the mistakes of mocha?#jest
Filter tests
This pattern of jest to let users filter the tests down easily and not running all tests feels like an anti-pattern to me.
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) November 4, 2020
Depdenency Injection
Another good piece of documentation which, if you properly listen to it whispering, tells you to inject dependencies that otherwise leak in.
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) May 19, 2020
Make them transparent, it hurts in the beginning, but pays off.https://t.co/CMGbRVChoW
see also https://t.co/2894cILEkk#jest
Jest Is Slow
Running the tests of one file with mocha takes 0.2s running the same tests with jest 1.5s ... why should I be waiting 1.3s more every time? What's the value added?
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) October 25, 2019
Various
Why do the tests fail when I have no test inside a test file?
— Wolfram (JS-- HTML++ CSS++) Kriesing (@wolframkriesing) May 19, 2020
A warning, ok, but it's not a test fail. I am an adult, please.
"Your test suite must contain at least one test."#jest