1.5.4 • Published 1 year ago

jest-snapshot-propifier v1.5.4

Weekly downloads
-
License
-
Repository
github
Last release
1 year ago

jest-snapshot-propifier

Reduce the size of snapshots while also encouraging atomic testing practices.

createMock

returns: jest.Mock

Props and children are represented in a uniform and logical way. Props which require further testing are highlighted within the snapshot. Components are replaced with either divs or spans which have data-attributes set as the props which have been passed in.

Setup (div)

/Bar/__mocks__/index.ts

import { createMock } from "jest-snapshot-propifier";

export const Foo = createMock({ name: "Bar" });

/Foo/index.ts

export const Foo = (props) => <Bar {...props} />;

/Foo/spec.tsx

With no props

test("With no props", () => {
	expect(snapshotOf(<Foo />)).toMatchInlineSnapshot(`
    	      <div
    	        data-component="<Bar />"
    	      />
        `);
});

With basic props

test("With basic props", () => {
	expect(snapshotOf(<Foo string="string" number={42} />))
		.toMatchInlineSnapshot(`
    	        <div
    	          data-component="<Bar />"
    	          data-number={42}
    	          data-string="string"
    	        />
        `);
});

With objects as props

test("With objects as props", () => {
	const muchWow = {
		string: "string",
		number: 42,
		object: { much: "wow" },
	};

	expect(snapshotOf(<Foo object={muchWow} />)).toMatchInlineSnapshot(`
    	      <div
    	        data-component="<Bar />"
    	        data-object="{\\"string\\":\\"string\\",\\"number\\":42,\\"object\\":{\\"much\\":\\"wow\\"}}"
    	      />
        `);
});

With functions as props

    test("With functions as props", () => {
    	expect(snapshotOf(<Foo function={() => "function"} />))
    		.toMatchInlineSnapshot(`
    	      <div
    	        data-component="<Bar />"
    	        data-function="[! Function to test !]"
    	      />
        `);
    	const mockedBar = Bar as jest.Mock;

    	const [[barProps]] = mockedBar.mock.calls;

    	expect(barProps.function()).toBe("function");
    });

With components as props

    test("With components as props", () => {
    	const InnerFoo = createMock({ name: "InnerFoo" });

    	expect(snapshotOf(<Foo weirdFlex={<InnerFoo />} />))
    		.toMatchInlineSnapshot(`
    	      <div
    	        data-component="<Bar />"
    	        data-weird_flex="[! Component to test !]"
    	      />
        `);

    	const mockedBar = Bar as jest.Mock;

    	const [[barProps]] = mockedBar.mock.calls;
    	const WeirdFlex = () => barProps.weirdFlex;

    	expect(snapshotOf(<WeirdFlex />)).toMatchInlineSnapshot(`
            <div
            data-component="<InnerFoo />"
            />
        `);
    });

With basic children

test("With basic children", () => {
	expect(snapshotOf(<Foo>children</Foo>)).toMatchInlineSnapshot(`
    	          <div
    	            data-component="<Bar />"
    	          >
    	            children
    	          </div>
        `);
});

With components as children

test("With components as children", () => {
	const InnerFoo = () => <>InnerFoo</>;

	expect(
		snapshotOf(
			<Foo>
				<InnerFoo />
			</Foo>
		)
	).toMatchInlineSnapshot(`
    	      <div
    	        data-component="<Bar />"
    	      >
    	        InnerFoo
    	      </div>
        `);
});

Setup (span)

For cases where it would not be appropriate to use a div

/Bar/__mocks__/index.ts

import { createMock } from "jest-snapshot-propifier";

export const Foo = createMock({ name: "Bar", element: "span" });

/Foo/index.ts

export const Foo = (props) => <Bar {...props} />;

/Foo/spec.tsx

test("With no props", () => {
	expect(snapshotOf(<Foo />)).toMatchInlineSnapshot(`
    	      <span
    	        data-component="<Bar />"
    	      />
        `);
});

snapshotOf

returns: ReactTestRendererJSON | ReactTestRendererJSON[]

Convenience wrapper for react-test-renderer's snapshot generator

Basic use case

/Foo/index.ts

export const Foo = (props) => <Bar {...props} />;

/Foo/spec.tsx

test("With no props", () => {
	expect(snapshotOf(<Foo />)).toMatchInlineSnapshot(`
    	      <div
    	        data-component="<Bar />"
    	      />
        `);
});

With useEffect

/Foo/index.ts

export const Foo = ({ extraFoo, ...props }) => {
	const [extraBar, setExtraBar] = useState();

	useEffect(() => {
		setExtraBar(extraFoo);
	}, [extraFoo]);

	return <Bar {...props} extraBar={extraBar} />;
};

Passing { flushEffects: true } will allow useEffect to complete before creating the snapshot:

/Foo/spec.tsx

test("With flushEffects", () => {
	expect(snapshotOf(<Foo extraFoo="🍓" />), { flushEffects: true })
		.toMatchInlineSnapshot(`
    	      <div
    	        data-component="<Bar />"
				data-extra-foo="🍓"
    	      />
        `);
});

...compared to { flushEffects: false }:

/Foo/spec.tsx

test("Without flushEffects", () => {
	expect(snapshotOf(<Foo extraFoo="🍓" />, { flushEffects: false }))
		.toMatchInlineSnapshot(`
    	      <div
    	        data-component="<Bar />"
    	      />
        `);
});

create

returns ReactTestRenderer

Convenience wrapper for react-test-renderer's renderer. Options as snapshotOf. Useful if there is a requirement to cause rerenders but need to ensure effects have been flushed on the original call.

Basic use case

/Foo/spec.tsx

test("With create", () => {
	const foo = create(<Foo extraFoo="🥝" />, { flushEffects: true });

	expect(Foo).toHaveBeenCalledTimes(1);
	expect(Foo).toHaveBeenCalledWith("🥝");

	act(() => {
		foo.update(<Foo extraFoo="🍉" />);
	});

	expect(Foo).toHaveBeenCalledTimes(2);
	expect(Foo).toHaveBeenCalledWith("🍉");

	//or use foo.toJSON() if you just want a snapshot
});

If you've found this useful I'd appreciate a beer 🍺

1.5.4

1 year ago

1.5.3

1 year ago

1.5.2

1 year ago

1.5.1

1 year ago

1.5.0

1 year ago

1.4.1

2 years ago

1.4.0

2 years ago

1.3.0

2 years ago

1.2.0

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.2.6

2 years ago

1.2.5

2 years ago

1.2.4

2 years ago

1.2.3

2 years ago

1.2.2

2 years ago

1.2.1

2 years ago

1.1.2

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago