tachyon-test-utils
v32.0.0
Published
Various testing utilities for the tachyon repo
Downloads
9
Readme
tachyon-test-utils
Helpers to improve unit testing.
Installation
$ yarn add -D tachyon-test-utils
React Component Testing Utilities
This package contains two utilities that simplify the process of scaffolding and testing React components. This is accomplished through the use of Enzyme.
Shallow Render Testing via createShallowWrapperFactory
Per the Shallow Render Enzyme docs:
Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure that your tests aren't indirectly asserting on behavior of child components.
Mount Render Testing via createMountWrapperFactory
Per the Mount Render Enzyme docs:
Full DOM rendering is ideal for use cases where you have components that may interact with DOM APIs or need to test components that are wrapped in higher order components.
It is almost always the right decision to use Enzyme's Shallow Render API unless you have a specific test case that can only be exercised in a Mount Render context.
Recommended Usage
Both createShallowWrapperFactory
and createMountWrapperFactory
are meant to
be consumed once per test file. The resulting callback that is returned is what
individual test cases should generally be using the base factory:
import { createShallowWrapperFactory } from 'tachyon-test-utils';
import { SomeComponent } from '.';
describe(SomeComponent, () => {
// If you have a top-level describe in your test framework, creator your factor inside of it
const setup = createShallowWrapperFactory(SomeComponent);
it('does something', () => {
// wrapper is the Component with props applied from the generator function you provided
// props are the props that were applied and are supplied for convenience
const { wrapper, props } = setup();
// ...
});
});
Overriding Default Props
The callback function ("setup" above) accepts a deep partial that will be recursively assigned over the default set of props that were specific. This is accomplished by Lodash's defaultsDeep utility.
For example:
import { createShallowWrapperFactory } from 'tachyon-test-utils';
import { SomeComponent } from '.';
describe(SomeComponent, () => {
// The typings will enforce that all mandatory props are present
// as part of the prop generator function argument.
const setup = createShallowWrapperFactory(SomeComponent, () => ({
foo: {
bar: true,
boink: 'bong',
},
roger: 'rabbit',
}));
it('behaves differently when the provided prop roger is dodger', () => {
const { wrapper, props } = setup({ roger: 'dodger' });
console.log(props); // { roger: 'doger', foo: { bar: true, boink: 'bong' } }
});
it("behaves differently when foo's bar value is false", () => {
const { wrapper, props } = setup({ foo: { bar: false } });
console.log(props); // { roger: 'rabbit', foo: { bar: false, boink: 'bong' } }
});
});
Mocking React Context (mount-only currently)
When testing components that use context, mocking useContext
or other custom
context hooks can have unintended side effects for descendent components. The
createMountWrapperFactory
extends the base enzyme options with
wrappingContexts
which accepts a generator function that returns an array of
context/value tuples. Similar to props, the final contexts used in rendering are
returned (as a Map):
import { createMountWrapperFactory } from 'tachyon-test-utils';
describe(SomeComponent, () => {
const setup = createMountWrapperFactory(SomeComponent, () => props, {
wrappingContexts: () => [
[primitiveContext, 42],
[complexContext, { foo: bar }],
],
});
it('has default context', () => {
const { contexts, wrapper } = setup();
console.log(contexts); // Map { primitiveContext => 42, complexContext => { foo: bar } }
});
});
To change or override context values on a per-test basis, the factory function's
second parameter object includes a similar wrappingContexts
option. This
option takes a bare tuple array and will override matching default mocked
contexts if any were provided and will freshly set values otherwise:
describe(SomeComponent, () => {
const setup = createMountWrapperFactory(SomeComponent, () => props, {
wrappingContexts: () => [
[context1, 1],
[context2, 2],
],
});
it('allows per-test context mocking', () => {
const { contexts, wrapper } = setup(props, {
wrappingContexts: [
[context1, 111],
[context3, 3],
],
});
console.log(contexts); // Map { context1 => 111, context2 => 2, context3 => 3 }
});
});
To update a context value in the middle of a test, the factory function also
returns an updateWrappingContext
function that can be used. It will update the
target context value and re-render the component:
describe(SomeComponent, () => {
const setup = createMountWrapperFactory(SomeComponent, () => props, {
wrappingContexts: () => [[contextA, 'a']],
});
it('updates ', () => {
const { updateWrappingContext, wrapper } = setup(props);
// wrapper rendered with contextA => 'a'
updateWrappingContext(contextA, 'notA');
// wrapper rendered with contextA => 'notA'
});
});
Note: This can be used with both default and per-test context configurations, as well as with contexts that hadn't previously been set in the test suite at all (e.g. in situations where the initial render is accomplished with a context's fallback value).
Other Useful Test Utils For Jest Utilities
These are common test utilities we endorse that integrate nicely into Jest:
Fetch Mocking - jest-fetch-mock