Cute matchers for vue-test-utils and Jest

Released jest-matcher-vue-test-utils

Kengo Hamasaki / hmsk
Hai-iro
2 min readOct 28, 2018

--

Recently, I released jest-matcher-vue-test-utils as an npm module.

I’m so happy if you put a star to the repository btw :)

Through working on many testings (I’ve written over 1k cases in this half a year apparently), found some repeating patterns and decided to consolidate as matchers.

Prop validations

The original idea is by Joseph Won who is my co-worker at Indiegogo. When we work on building Vue component, starting from thinking about interfaces (props/events).

The prop validations of Vue component doesn’t work (won’t block unintentional props) on a production build. That just puts warnings on development build, so we may miss the problem on props interfaces rather than general validators. Then I intended to have enough tests for prop validations during I’m building Vue components before many engineers work on. But that requires annoying mock for the warnings.

If you do that with Jest and vue-test-utils straightly,

console.error = jest.fn();
mount(Component, { propsData });
expect(console.error).toHaveBeenCalled();
console.error = original; // Restore with some ways

so the module provides the matcher to write above lines with a single line like:

expect(Component).toBeValidProps({ name: "required name", fullName: "Kengo Hamasaki" });`

toBeValidProps asserts that validation error happens.

Also having other handy matchers:

  • toBeValidProp : Check a single prop
  • toRequireProp : Check a prop is required
  • toHaveDefaultProp : Check a prop gives a default value
  • toBeValidPropWithTypeCheck : Check a prop passes type check
  • toBeValidPropWithCustomValidator : Check a prop passes custom validation

As mentioned above, testing prop validations can’t guarantee the component works with only expected props as Vue’s behavior. So we may need some other ways (exists npm module perhaps?) to halt component strictly by failing prop validations essentially.

Changing an existence

Here’s another repeating pattern:

const wrapper = shallowMount(Component);
expect(wrapper.contains('#that')).toBe(true);
clickSomething();
expect(wrapper.contains('#that')).toBe(false);

As a childhood friend of RSpec, I craved the way like:

expect { do_something }.to change { object.attribute }

So, created a similar matcher for Jest + vue-test-utils:

const wrapper = shallowMount(Component);
expect(clickSomething).toHide('#that');

You can pass “the action for making changes” and assert “hiding the exact content on the mounted Vue component”. Also, there’s toShow for checking “hiding -> showing” too :)

I wondered if Jest provides the general interface to check before/after of function/promise runs though.

Will add more

Recently, I face the implementation works again and seeing some other repeatings (Especially around mocking Vuex), so will update continuously.

And happy to hear other cases you’re seeing and supporting on the module ✨

--

--