84 lines
3 KiB
Plaintext
84 lines
3 KiB
Plaintext
[[development-unit-tests]]
|
|
=== Unit Testing
|
|
|
|
We use unit tests to make sure that individual software units of {kib} perform as they were designed to.
|
|
|
|
[float]
|
|
=== Current Frameworks
|
|
|
|
{kib} is migrating unit testing from `Mocha` to `Jest`. Legacy unit tests still exist in `Mocha` but all new unit tests should be written in `Jest`.
|
|
|
|
[float]
|
|
==== Mocha (legacy)
|
|
|
|
Mocha tests are contained in `__tests__` directories.
|
|
|
|
*Running Mocha Unit Tests*
|
|
|
|
["source","shell"]
|
|
-----------
|
|
yarn test:mocha
|
|
-----------
|
|
|
|
[float]
|
|
==== Jest
|
|
Jest tests are stored in the same directory as source code files with the `.test.{js,ts,tsx}` suffix.
|
|
|
|
*Running Jest Unit Tests*
|
|
|
|
["source","shell"]
|
|
-----------
|
|
yarn test:jest
|
|
-----------
|
|
|
|
[float]
|
|
===== Writing Jest Unit Tests
|
|
|
|
In order to write those tests there are two main things you need to be aware of.
|
|
The first one is the different between `jest.mock` and `jest.doMock`
|
|
and the second one our `jest mocks file pattern`. As we are running `js` and `ts`
|
|
test files with `babel-jest` both techniques are needed
|
|
specially for the tests implemented on Typescript in order to benefit from the
|
|
auto-inference types feature.
|
|
|
|
[float]
|
|
===== Jest.mock vs Jest.doMock
|
|
|
|
Both methods are essentially the same on their roots however the `jest.mock`
|
|
calls will get hoisted to the top of the file and can only reference variables
|
|
prefixed with `mock`. On the other hand, `jest.doMock` won't be hoisted and can
|
|
reference pretty much any variable we want, however we have to assure those referenced
|
|
variables are instantiated at the time we need them which lead us to the next
|
|
section where we'll talk about our jest mock files pattern.
|
|
|
|
[float]
|
|
===== Jest Mock Files Pattern
|
|
|
|
Specially on typescript it is pretty common to have in unit tests
|
|
`jest.doMock` calls which reference for example imported types. Any error
|
|
will thrown from doing that however the test will fail. The reason behind that
|
|
is because despite the `jest.doMock` isn't being hoisted by `babel-jest` the
|
|
import with the types we are referencing will be hoisted to the top and at the
|
|
time we'll call the function that variable would not be defined.
|
|
|
|
In order to prevent that we develop a protocol that should be followed:
|
|
|
|
- Each module could provide a standard mock in `mymodule.mock.ts` in case
|
|
there are other tests that could benefit from using definitions here.
|
|
This file would not have any `jest.mock` calls, just dummy objects.
|
|
|
|
- Each test defines its mocks in `mymodule.test.mocks.ts`. This file
|
|
could import relevant mocks from the generalised module's mocks
|
|
file `(*.mock.ts)` and call `jest.mock` for each of them. If there is
|
|
any relevant dummy mock objects to generalise (and to be used by
|
|
other tests), the dummy objects could be defined directly on this file.
|
|
|
|
- Each test would import its mocks from the test mocks
|
|
file mymodule.test.mocks.ts. `mymodule.test.ts` has an import
|
|
like: `import * as Mocks from './mymodule.test.mocks'`,
|
|
`import { mockX } from './mymodule.test.mocks'`
|
|
or just `import './mymodule.test.mocks'` if there isn't anything
|
|
exported to be used.
|
|
|
|
|