You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This test is fairly self explanatory. We `shallowMount` the component, set the username and use the `trigger` method `vue-test-utils` provides to simulate user input. `trigger` works on custom events, as well as events that use modifiers, like `submit.prevent`, `keydown.enter`, and so on.
80
81
81
-
This test also follows the three steps of unit testing:
82
+
Notice after calling `trigger`, we do `await wrapper.vm.$nextTick()`. This is why we had to mark the test as `async` - so we can use `await`. As of `vue-test-utils` beta 28, you need to call `nextTick` to ensure Vue's reactivity system updates the DOM. Sometimes you can get away without calling `nextTick`, but if you components start to get complex, you can hit a race condition and your assertion might run before Vue has updated the DOM. You can read more about this in the official [vue-test-utils documentation](https://vue-test-utils.vuejs.org/guides/#updates-applied-by-vue).
83
+
84
+
The above test also follows the three steps of unit testing:
82
85
83
86
1. arrange (set up for the test. In our case, we render the component).
84
87
2. act (execute actions on the system)
@@ -242,6 +245,8 @@ it("reveals a notification when submitted", async () => {
242
245
})
243
246
```
244
247
248
+
Using `flush-promises` has the nice side effect of ensuring all the promises, including `nextTick` have resolved, and Vue has updated the DOM.
249
+
245
250
Now the test passes. The source code for `flush-promises` is only about 10 lines long, if you are interested in Node.js it is worth reading and understanding how it works.
246
251
247
252
We should also make sure the endpoint and payload are correct. Add two more assertions to the test:
* Notice the tests are marked `await` and call `nextTick`. See [here](/simulating-user-input.html#writing-the-test) for more details on why.
104
+
99
105
As usual, we start by importing the various modules for the test. Notably, we are importing the actual routes we will be using for the application. This is ideal in some ways - if the real routing breaks, the unit tests should fail, letting us fix the problem before deploying the application.
100
106
101
107
We can use the same `localVue` for all the `<App>` tests, so it is declared outside the first `describe` block. However, since we might like to have different tests for different routes, the router is defined inside the `it` block.
@@ -326,10 +332,11 @@ import mockModule from "@/bust-cache.js"
That's a lot of code. Nothing too exciting is happening, though. We create a `localVue` and use Vuex, then create a store, passing a Jest mock function (`jest.fn()`) in place of the `testMutation`. Vuex mutations are always called with two arguments: the first is the current state, and the second is the payload. Since we didn't declare any state for the store, we expect it to be called with an empty object. The second argument is expected to me `{ msg: "Test Commit" }`, which is hard coded in the component.
99
+
Notice the tests are marked `await` and call `nextTick`. See [here](/simulating-user-input.html#writing-the-test) for more details on why.
100
+
101
+
There is a lot code in the test above - nothing too exciting is happening, though. We create a `localVue` and use Vuex, then create a store, passing a Jest mock function (`jest.fn()`) in place of the `testMutation`. Vuex mutations are always called with two arguments: the first is the current state, and the second is the payload. Since we didn't declare any state for the store, we expect it to be called with an empty object. The second argument is expected to me `{ msg: "Test Commit" }`, which is hard coded in the component.
98
102
99
103
This is a lot of boilerplate code to write, but is a correct and valid way to verify components are behaving correctly. Another alternative that requires less code is using a mock store. Let's see how to do that for while writing a test to assert `testAction` is dispatched.
100
104
@@ -106,7 +110,7 @@ Let's see the code, then compare and contrast it to the previous test. Remember,
106
110
2. the payload is correct
107
111
108
112
```js
109
-
it("dispatches an action when a button is clicked", () => {
113
+
it("dispatches an action when a button is clicked", async() => {
110
114
constmockStore= { dispatch:jest.fn() }
111
115
constwrapper=shallowMount(ComponentWithButtons, {
112
116
mocks: {
@@ -115,6 +119,7 @@ it("dispatches an action when a button is clicked", () => {
115
119
})
116
120
117
121
wrapper.find(".dispatch").trigger("click")
122
+
awaitwrapper.vm.$nextTick()
118
123
119
124
expect(mockStore.dispatch).toHaveBeenCalledWith(
120
125
"testAction" , { msg:"Test Dispatch" })
@@ -131,7 +136,7 @@ The third and final example shows another way to test that an action was dispatc
131
136
132
137
133
138
```js
134
-
it("dispatch a namespaced action when button is clicked", () => {
139
+
it("dispatch a namespaced action when button is clicked", async() => {
135
140
conststore=newVuex.Store()
136
141
store.dispatch=jest.fn()
137
142
@@ -140,6 +145,7 @@ it("dispatch a namespaced action when button is clicked", () => {
0 commit comments