jest-shallow-serializer
v1.1.2
Published
A flexible jest serializer for shallow rendering React components. Unlike full shallow renderers, this tool focuses on serializing only the components you pick, making snapshots cleaner and more focused. Perfect for targeted testing with minimal noise
Maintainers
Readme
jest-shallow-serializer
A flexible jest serializer for shallow rendering React components. Unlike full shallow renderers, this tool focuses on serializing only the components you pick, making snapshots cleaner and more focused. Perfect for targeted testing with minimal noise! 🚀
Motivation
I created this package because existing solutions for shallow rendering are no longer maintained, and the testing ecosystem seems to be shifting toward other approaches. However, I still believe shallow rendering is a valuable technique for isolating and testing components effectively, and this serializer aims to fill that gap.
Installation
- Install package
npm install jest-shallow-serializer --save-dev- Add
jest-shallow-serializertocompilerOptionstypes (intsconfig.json):
"types": ["jest-shallow-serializer"]- Add
jest-shallow-serializerto snapshot serializers (injest.configfile):
"snapshotSerializers": ["jest-shallow-serializer/serializer"]- Extend
globalscope (injest.configfile):
"setupFilesAfterEnv": ["<rootDir>/jest.setup.js"]jest.setup.js
import { doShallow, shallowWrapper, shallowed } from "jest-shallow-serializer";
Object.assign(global, {
doShallow,
shallowWrapper,
shallowed,
});- (Optional) You might need to add
doShallow,shallowWrapperandshallowedas globals (ineslint.config):
"globals": {
"doShallow": "readonly",
"shallowWrapper": "readonly",
"shallowed": "readonly"
},Usage
Unlike enzyme#shallow or react-test-renderer/shallow, this library performs selective shallow rendering. Developers choose specific components to shallow render by mocking them. There are two ways to mock a component:
1. shallowWrapper, shallowed and jest.mock
import * as componentModule from "@/app/module/Component";
import { App } from "@/app/module/App";
jest.mock(
"@/app/module/Component",
shallowWrapper("@/app/module/Component", "ComponentName")
);
const shallowedComponentModule = shallowed(componentModule);2. doShallow + require
doShallow use jest.doMock, which is not hoisted, that's why we need to require shallowed module afterwards.
import { App } from "@/app/module/App";
const shallowedComponentModule = doShallow(
"@/app/module/Component",
"ComponentName"
);
const { ComponentName } = require("@/app/module/Component");After obtaining shallowedComponentModule, we can use it to mock / unmock a component:
describe("Component", () => {
afterEach(() => {
shallowedComponentModule.unmock("ComponentName");
});
it("matches snapshot", () => {
shallowedComponentModule.mock("ComponentName");
const { asFragment } = render(<App />);
expect(asFragment()).toMatchSnapshot();
});
it("next test", () => {
render(<App />); // here `ComponentName` won't be shallowed
});
});Nested exports / Context
You can also use dot notation in component names to shallow mock nested components. For example, if you want to mock context provider, simply use Context.Provider as the component name.
src
├── context.ts
├── Component.tsx
├── Component.spec.tsxcontext.ts
export const Context = createContext<string | undefined>(undefined);Component.tsx
import { Context } from "./context";
export const Component = ({ children }: TestComponentContextProps) => {
return <Context.Provider value="lorem ipsum">{children}</Context.Provider>;
};Component.spec.tsx
import { Component } from "./Component";
import { Context } from "./context";
jest.mock("./context", shallowWrapper("./context", "Context.Provider"));
const shallowedProvider = shallowed(Context);
describe("Component", () => {
afterEach(() => {
shallowedProvider.unmock("Context.Provider");
});
it("matches snapshot", () => {
shallowedProvider.mock("Context.Provider");
const { asFragment } = render(<Component />);
expect(asFragment()).toMatchSnapshot();
});
});