destroytoday.com

Shaping Vuex through testing

Today, I started setting up the Vuex store for the modern Cushion exploration. In the current Cushion, without Vuex tests, all the modules live in their own files, which house their states, getters, actions, and mutations. I started setting up the new Vuex store this same way, but now that I have a proper test suite, it quickly became clear that this structure wouldn’t work. This is actually a side benefit of having tests—when it’s difficult to write a test, that’s a code smell.

In this case, I needed to break the Vuex modules into separate methods, which would let me test them as basic functions instead of part of the entire module tree. For mutations, I could simply pass a setup state and payload, then expect the result. For actions, I could easily spy commit and dispatch to test what gets called. I’m still keeping everything local, so I haven’t had to mock any requests, but I’m sure this will be as straightforward as using jest.mock.

I did pick up a nice trick for setting up a fresh module state for testing that I didn’t know about before. Apparently, you can represent the state as a function that returns the object rather than the straight object. While I believe this is intended for reusing modules, I find it useful for providing a test helper. When importing, I can import as a “create” method, then call it in the beforeAll hook:

import { state as createState } from "@/store"

let state;

beforeEach(() => {
  state = createState();
})

It’s still early, but I feel really good about the new structure. It just makes sense to me to keep it simple and test everything as regular functions. The last thing I’d want is for tests to feel so heavy and complex that I start copy/pasting a bunch of cruft or losing confidence in my tests. I’m sure there will be hurdles along the way to figure out, but I’m actually not going to think about those right now—only happy thoughts.