← Back

Wrapper Factory Pattern for Dynamic Unit Test

Published

14 October 2023

Tags

Unit Test

Problem

When writing a complex unit test to your component, oftentimes you'll be faced the situation of repeating the component wrapper initialization to cover multiple test cases. This redundant initialization occurs because the test case cannot be handled by single component initialization, either you found it hard to change the value inside the single wrapper or any other reason.

Let's start with a simple unit test problem.

beforeAll(() => {
	localVue = null;
    localVue = createLocalVue();
    localVue.use(Buefy);
});

beforeEach(() => {
    jest.resetModules();
    jest.clearAllMocks();

	wrapper = shallowMount(MyComponent, {
		localVue,
		propsData: {
			items: ["item 1", "item 2"]
		}
	};
});

afterEach(() => {
    wrapper. Destroy();
});

describe("MyComponent", () => {
	test("render given items in props", () => {
		expect(wrapper.findAll(".item").length).toBe(2);
	});
});

As above unit test example, when you want to change the value of propsData to test another case you may use wrapper.setData(). Somehow in more complex case, you cannot simply use it, so repeating the initiation of component wrapper is a solution.

What if the options inside the component wrapper initiation is quite a lot? Is there any practice to simplify it?

Actually, there're multiple practice to do so, but in this documentation, we will explain about Wrapper Factory pattern.

Wrapper Factory

By this way, you might write a unit test cleaner by using a wrapper factory. The idea is we provide a single function that return a Wrapper that will be used in every test case. This function receives a parameter that act as props for Jest wrapper initiation (mount or shallowMount).

function wrapperFactory({ propsData } = {}) {
	return shallowMount(MyComponent, {
		propsData
	});
}

beforeAll(() => {
	localVue = null;
    localVue = createLocalVue();
    localVue.use(Buefy);
});

beforeEach(() => {
    jest.resetModules();
    jest.clearAllMocks();
});

describe("MyComponent", () => {
	test("render given items in props", () => {
		const wrapper = wrapperFactory({
			propsData: {
				items: ["item 1", "item 2"]
			}
		});
		expect(wrapper.findAll(".item").length).toBe(2);
	});

	test("not render anything because items props is empty", () => {
		const wrapper = wrapperFactory({
			propsData: {
				items: []
			}
		});
		expect(wrapper.findAll(".item").length).toBe(0);
	});
});

In the code snippet above, we've created a wrapperFactory() function which will cover the common case. You can provide additional options that you need in the function parameters based on your test cases.