Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Testing Actions Documentation to No Longer Reference inject-loader #2155

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 20 additions & 55 deletions docs/guide/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ describe('mutations', () => {

## Testing Actions

Actions can be a bit more tricky because they may call out to external APIs. When testing actions, we usually need to do some level of mocking - for example, we can abstract the API calls into a service and mock that service inside our tests. In order to easily mock dependencies, we can use webpack and [inject-loader](https://github.com/plasticine/inject-loader) to bundle our test files.
Actions can be a bit more tricky because they may call out to external APIs. When testing actions, we usually need to do some level of mocking and spying - for example, we can abstract the API calls into a service and mock that service inside our tests.

Example testing an async action:
The following code assumes your testing environment uses [Sinon.JS](http://sinonjs.org/):

```js
// actions.js
Expand All @@ -70,72 +70,37 @@ export const getAllProducts = ({ commit }) => {
```js
// actions.spec.js

// use require syntax for inline loaders.
// with inject-loader, this returns a module factory
// that allows us to inject mocked dependencies.
import { expect } from 'chai'
const actionsInjector = require('inject-loader!./actions')

// create the module with our mocks
const actions = actionsInjector({
'../api/shop': {
getProducts (cb) {
setTimeout(() => {
cb([ /* mocked response */ ])
}, 100)
}
}
})

// helper for testing action with expected mutations
const testAction = (action, payload, state, expectedMutations, done) => {
let count = 0

// mock commit
const commit = (type, payload) => {
const mutation = expectedMutations[count]

try {
expect(type).to.equal(mutation.type)
expect(payload).to.deep.equal(mutation.payload)
} catch (error) {
done(error)
}

count++
if (count >= expectedMutations.length) {
done()
}
}

// call the action with mocked store and arguments
action({ commit, state }, payload)
describe('actions', () => {
it('getAllProducts', () => {
const commit = sinon.spy()
const state = {}

// check if no mutations should have been dispatched
if (expectedMutations.length === 0) {
expect(count).to.equal(0)
done()
}
}
actions.getAllProducts({ commit, state })

describe('actions', () => {
it('getAllProducts', done => {
testAction(actions.getAllProducts, null, {}, [
{ type: 'REQUEST_PRODUCTS' },
{ type: 'RECEIVE_PRODUCTS', payload: { /* mocked response */ } }
], done)
expect(commit.args).to.deep.equal([
['REQUEST_PRODUCTS'],
['RECEIVE_PRODUCTS', { /* mocked response */ }]
])
})
})
```

If you have spies available in your testing environment (for example via [Sinon.JS](http://sinonjs.org/)), you can use them instead of the `testAction` helper:

If your environment uses [Jest](http://jestjs.io/):
```js
import shop from '../api/shop'

describe('actions', () => {
it('getAllProducts', () => {
const commit = sinon.spy()
const commit = jest.fn()
const state = {}

let getProductsSpy = jest.spyOn(shop, 'getProducts')
getProductsSpy.mockImplementation(() => {
return [ /* mocked response */]
});

actions.getAllProducts({ commit, state })

expect(commit.args).to.deep.equal([
Expand Down