Reputation: 1326
Disclaimer: I am pretty new to Vue, JavaScript, and web frameworks in general.
I'm trying to familiarise myself with some basic unit and component tests using Jest and vue-test-utils.
I have read the docs on vue-test-utils
' mount() and shallowMount()
, but I'm not sure when to use the one over the other (they appear to be very similar).
According to the docs on shallowMount()
:
Like mount, it creates a Wrapper that contains the mounted and rendered Vue component, but with stubbed child components.
What exactly is meant by "stubbed child components"?
Can mount()
and shallowMount()
be used interchangeably?
Upvotes: 35
Views: 17080
Reputation: 2512
I disagree with Thomas Ferro, while his explanation of their function is correct, I disagree with what method to use. In my opinion you should always use mount
instead of shallowMount
.
To explain this I will refer to an article by Martin Fowler: https://martinfowler.com/articles/mocksArentStubs.html
There are two different types of TDD: mockist and classical TDD. When you mock everything, your test will know a lot about (some) dependencies. So if a method from a child component/ dependency is triggered, your test knows about it.
In classical TDD you should only mock the Boundary layer (web calls, filesystem calls, database calls, view calls), nothing else. So the name "unit" or System Under Test does not imply a single object but instead can be a collection of objects.
This means that with the mockist style it will also break when this method changes its method name. Instead the benefit of classical TDD is that you dont know that method name (and do not care).
Think of it (classical TDD) as throw in some variables as input and verify an output or state. Ignore all details in between. The benefit of doing so is one of the benefits of TDD, which is lost in the mockist style, that you can refactor and transform your code fearlessly. If you change a method name of a dependency (a refectoring) your test will still pass, because the method is not mocked.
Treat the test if the dependency does not exist (only in the construct). Again the only exceptions are web calls (http requests), repository calls (database/ file systems), view calls.
So if you refactor your child component to the main component or to another child component, your test still passes. Because classical TDD validates input and output (and state), not dependencies.
Upvotes: 7
Reputation: 2442
What the documentation means by "stubbed child components" is that every components within the tested one will not be rendered. Instead, you will have a placeholder component.
This prevent your tests to be parasite by other component's behaviors.
In my opinion, you should always shallow mount your components when doing unit tests, and simply mount them when doing tests in your entire application.
Upvotes: 56