Two ways to represent (render)
vue-test-utils
provides two ways to render, or mount a component – mount
and shallowMount
. A component mounted by one of two methods returns a wrapper
, an object containing the Vue component, along with a number of methods for testing.
We start with two simple components:
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">const</span> Child <span class="token operator">=</span> Vue <span class="token punctuation">.</span> <span class="token function">component</span> <span class="token punctuation">(</span> <span class="token string">"Child"</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> name <span class="token punctuation">:</span> <span class="token string">"Child"</span> <span class="token punctuation">,</span> template <span class="token punctuation">:</span> <span class="token string">"<div>Child component</div>"</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">const</span> Parent <span class="token operator">=</span> Vue <span class="token punctuation">.</span> <span class="token function">component</span> <span class="token punctuation">(</span> <span class="token string">"Parent"</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> name <span class="token punctuation">:</span> <span class="token string">"Parent"</span> <span class="token punctuation">,</span> template <span class="token punctuation">:</span> <span class="token string">"<div><child /></div>"</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
We start rendering Child
and call the html
method that vue-test-utils
provides to check markup.
1 2 3 4 5 6 | <span class="token keyword">const</span> shallowWrapper <span class="token operator">=</span> <span class="token function">shallowMount</span> <span class="token punctuation">(</span> Child <span class="token punctuation">)</span> <span class="token keyword">const</span> mountWrapper <span class="token operator">=</span> <span class="token function">mount</span> <span class="token punctuation">(</span> Child <span class="token punctuation">)</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> shallowWrapper <span class="token punctuation">.</span> <span class="token function">html</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> mountWrapper <span class="token punctuation">.</span> <span class="token function">html</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> |
Both mountWrapper.html()
and shallowWrapper.html()
will produce the following result:
1 2 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Child component <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> |
There is no difference, so we will try to do the same test against Parent
?
1 2 3 4 5 6 | <span class="token keyword">const</span> shallowWrapper <span class="token operator">=</span> <span class="token function">shallowMount</span> <span class="token punctuation">(</span> Parent <span class="token punctuation">)</span> <span class="token keyword">const</span> mountWrapper <span class="token operator">=</span> <span class="token function">mount</span> <span class="token punctuation">(</span> Parent <span class="token punctuation">)</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> shallowWrapper <span class="token punctuation">.</span> <span class="token function">html</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> mountWrapper <span class="token punctuation">.</span> <span class="token function">html</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> |
mountWrapper.html()
is now:
1 2 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> Child component <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> |
Parent
and Child
both render the same. On the other hand, shallowWrapper.html()
produces the following result:
1 2 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> div</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> vuecomponent-stub</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> vuecomponent-stub</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> div</span> <span class="token punctuation">></span></span> |
In <Child />
is replaced by <vuecomponent-stub />
. shallowMount
renders normal html elements, but replaces Vue components with stub.
A stub is a type of “fake” object that represents an actual object.
Imagine you want to test your App.vue
, which looks like this:
1 2 3 4 5 6 7 | <template> <div> <h1>My Vue App</h1> <fetch-data /> </div> </template> |
And we want to test that <h1>My Vue App</h1>
will be rendered correctly. We also have a component <fetch-data>
, will request external API calls in mounted
the hook lifecycle.
If we use mount
, even though all we want to do is check the rendered text comparison, <fetch-data />
will invoke the request API. This will make our testing process slow and easily fail due to too many things that are difficult to control. So we use stub to create as a real object. By using shallowMount
, <fetch-data />
will be replaced with a <vuecomponent-stub />
, and the call to API request will not need to use it.
Reference
Translated from: https://lmiller1990.github.io/vue-testing-handbook/rendering-a-component.html