Set props with propsData
propsData
can be used with both mount
and shallowMount
. It is often used to check components that receive props from its parent component.
propsData
is passed the second argument of either shallowMount
or mount
as follows:
1 2 3 4 5 6 | <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">shallowMount</span> <span class="token punctuation">(</span> Foo <span class="token punctuation">,</span> <span class="token punctuation">{</span> propsData <span class="token punctuation">:</span> <span class="token punctuation">{</span> foo <span class="token punctuation">:</span> <span class="token string">'bar'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
Create a component model
Creating a simple <SubmitButton>
component has two props
: msg
and isAdmin
. Depending on the value of isAdmin
, this component will contain a <span>
in two states:
Not Authorized
ifisAdmin
is false (or not adopted as a prop)Admin Privileges
ifisAdmin
is true
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> template</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> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> span</span> <span class="token attr-name">v-if</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> isAdmin <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Admin Privileges <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> span</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> span</span> <span class="token attr-name">v-else</span> <span class="token punctuation">></span></span> Not Authorized <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> span</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token punctuation">></span></span> {{ msg }} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</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> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> template</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> script</span> <span class="token punctuation">></span></span> <span class="token script language-javascript"> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> name <span class="token punctuation">:</span> <span class="token string">"SubmitButton"</span> <span class="token punctuation">,</span> props <span class="token punctuation">:</span> <span class="token punctuation">{</span> msg <span class="token punctuation">:</span> <span class="token punctuation">{</span> type <span class="token punctuation">:</span> String <span class="token punctuation">,</span> required <span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> isAdmin <span class="token punctuation">:</span> <span class="token punctuation">{</span> type <span class="token punctuation">:</span> Boolean <span class="token punctuation">,</span> <span class="token keyword">default</span> <span class="token punctuation">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> script</span> <span class="token punctuation">></span></span> |
Create the first test
We will make a confirmation about the notification in case the user does not have admin rights.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token keyword">import</span> <span class="token punctuation">{</span> shallowMount <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@vue/test-utils'</span> <span class="token keyword">import</span> SubmitButton <span class="token keyword">from</span> <span class="token string">'@/components/SubmitButton.vue'</span> <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">'SubmitButton.vue'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">it</span> <span class="token punctuation">(</span> <span class="token string">"displays a non authorized message"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> msg <span class="token operator">=</span> <span class="token string">"submit"</span> <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">shallowMount</span> <span class="token punctuation">(</span> SubmitButton <span class="token punctuation">,</span> <span class="token punctuation">{</span> propsData <span class="token punctuation">:</span> <span class="token punctuation">{</span> msg <span class="token punctuation">:</span> msg <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> wrapper <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> <span class="token function">expect</span> <span class="token punctuation">(</span> wrapper <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token string">"span"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">text</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token string">"Not Authorized"</span> <span class="token punctuation">)</span> <span class="token function">expect</span> <span class="token punctuation">(</span> wrapper <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token string">"button"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">text</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token string">"submit"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
Run the test with yarn test:unit
. The results we get:
1 2 3 4 | PASS tests/unit/SubmitButton.spec.js SubmitButton.vue ✓ displays a non authorized message (15ms) |
The results of console.log(wrapper.html())
also printed:
1 2 3 4 5 6 7 | <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> span</span> <span class="token punctuation">></span></span> Not Authorized <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> span</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token punctuation">></span></span> submit <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</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> |
We can see that the msg
prop is processed and the markup is exactly what is displayed.
Create the second experiment
We will check the status when isAdmin
is true
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token keyword">import</span> <span class="token punctuation">{</span> shallowMount <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@vue/test-utils'</span> <span class="token keyword">import</span> SubmitButton <span class="token keyword">from</span> <span class="token string">'@/components/SubmitButton.vue'</span> <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">'SubmitButton.vue'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">it</span> <span class="token punctuation">(</span> <span class="token string">'displays a admin privileges message'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> msg <span class="token operator">=</span> <span class="token string">"submit"</span> <span class="token keyword">const</span> isAdmin <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">shallowMount</span> <span class="token punctuation">(</span> SubmitButton <span class="token punctuation">,</span> <span class="token punctuation">{</span> propsData <span class="token punctuation">:</span> <span class="token punctuation">{</span> msg <span class="token punctuation">,</span> isAdmin <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token function">expect</span> <span class="token punctuation">(</span> wrapper <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token string">"span"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">text</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token string">"Admin Privileges"</span> <span class="token punctuation">)</span> <span class="token function">expect</span> <span class="token punctuation">(</span> wrapper <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token string">"button"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">text</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token string">"submit"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
Run the test with yarn test:unit
and test the results:
1 2 3 4 | PASS tests/unit/SubmitButton.spec.js SubmitButton.vue ✓ displays a admin privileges message <span class="token punctuation">(</span> 4ms <span class="token punctuation">)</span> |
We also have markup with console.log(wrapper.html())
:
1 2 3 4 5 6 7 | <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> span</span> <span class="token punctuation">></span></span> Admin Privileges <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> span</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token punctuation">></span></span> submit <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</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> |
It can be seen that prop isAdmin
is used to render the <span>
element correctly.
Refactoring the tests again
We will refactor tests that comply with “Don’t Repeat Yourself” (DRY). Since all tests pass, we can be confident to refactor them again. As long as all tests are still passable after refactor, make sure not to break anything.
Refactor with Factory Function
In both tests, we call shallowMount
and then use the propsData
object repeatedly. We can refactor it again by using a factory function. A factory function is a function that returns an object – it creates objects, hence the name “factory” function.
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">const</span> msg <span class="token operator">=</span> <span class="token string">"submit"</span> <span class="token keyword">const</span> <span class="token function-variable function">factory</span> <span class="token operator">=</span> <span class="token punctuation">(</span> propsData <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">shallowMount</span> <span class="token punctuation">(</span> SubmitButton <span class="token punctuation">,</span> <span class="token punctuation">{</span> propsData <span class="token punctuation">:</span> <span class="token punctuation">{</span> msg <span class="token punctuation">,</span> <span class="token operator">...</span> propsData <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Above is a function that will shallowMount
a SubmitButton
component. We can pass any props to change the first factory
argument. DRY the tests with the factory function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">"SubmitButton"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">"has admin privileges"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">it</span> <span class="token punctuation">(</span> <span class="token string">"renders a message"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">factory</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token function">expect</span> <span class="token punctuation">(</span> wrapper <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token string">"span"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">text</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token string">"Not Authorized"</span> <span class="token punctuation">)</span> <span class="token function">expect</span> <span class="token punctuation">(</span> wrapper <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token string">"button"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">text</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token string">"submit"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token function">describe</span> <span class="token punctuation">(</span> <span class="token string">"does not have admin privileges"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">it</span> <span class="token punctuation">(</span> <span class="token string">"renders a message"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">factory</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> isAdmin <span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token function">expect</span> <span class="token punctuation">(</span> wrapper <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token string">"span"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">text</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token string">"Admin Privileges"</span> <span class="token punctuation">)</span> <span class="token function">expect</span> <span class="token punctuation">(</span> wrapper <span class="token punctuation">.</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token string">"button"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">text</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toBe</span> <span class="token punctuation">(</span> <span class="token string">"submit"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> |
Run the test again. Everything to pass easily.
1 2 3 4 5 6 7 | PASS tests/unit/SubmitButton.spec.js SubmitButton has admin privileges ✓ renders a message (26ms) does not have admin privileges ✓ renders a message (3ms) |
Conclude
- By using
propData
passes when mounting a component, you can set theprops
used in the test. - Factory functions can be used to DRY your tests
- Instead of using
propsData
, we can also usesetProps
to set props values during testing.
Reference
Translated from: https://lmiller1990.github.io/vue-testing-handbook/components-with-props.html#setting-props-with-propsdata