Working an application in Vue.js with TDD — An extensive guide for people who have time — part 5
Testing with third party libs
This is the fifth in a series of articles:
- Part 1: Setup and the first test
- Part 2: Continuing the UserView
- Part 3: Testing the store and the rest of the presentation components
- Part 4: Testing the API request service
- Part 5: Adding and testing with third-party dependencies
- Part 6: Overview — 26/11
If you want to read it in pt-BR, check it out here.
In the last article, we have finished our application 👏
And in this article we’ll look at how to integrate our application with a thir-party library, and how to update our tests to handle this change.
Improving the appearance + Third-party libs
We can style our components manually. I usually do this due to my job context, but here I want to show how we can then style our components using a third-party library. I’ve never used it, but let’s give it a shot. We are going to use the ElementUI.
We can download it through the Vue CLI. But, let’s download and install it manually
npm i -d element-ui
Then, let’s install it in our project.
// src/main.jsimport Vue from 'vue'
import Element from 'element-ui'
import App from './App.vue'
import router from './router'
import store from './store'
import './registerServiceWorker'
import 'element-ui/lib/theme-chalk/index.css'Vue.use(Element)
Vue.config.productionTip = falsenew Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
Insert the markup base in the App.vue
// App.vue<template>
<el-container>
<el-main>
<router-view/>
</el-main>
</el-container>
</template>
Our tests are still passing, and we can move on make layout alterations.
Here we have just made our first bigrefactor relating the appearance. Basically, we gave a new layout to the form part of our application:
Awesome! Our form looks better, but:
Our tests are failing. But, what exactly is going on here?
Well… as we downloaded the ElementUI as third-party dependency and we made its booting on main.js
when we make use of the elements inside the tests of our component VUserSearchForm.vue
, our component used on the test doesn’t know the ElementUI. Then, we need to go back to the tests file and do exactly what we did on main.js
Perfect. We insert here the dependency of createLocalVue
in line 1, and also import ElementUI
in line 2.
After, we create a local instance and use the ElementUI
on lines 5 and 6 and add the local instance as an option when we render our component in line 10. Basically, what we have seen with the Vuex
case 😄
Now, it’s only necessary to update the snapshot and we are going to have more concise information:
Here, we only need to update our selectors references to search for our HTML classes.
const build = () => {
const wrapper = shallowMount(VUserSearchForm, { localVue })return {
wrapper,
input: () => wrapper.find('.search-form__input'),
button: () => wrapper.find('.search-form__button'),
}
}
But wait! How is the input test passing and the button one isn’t?
What happens is that we are rendering an el-input
, which is a customized element by ElementUI, so we need to put our button in it to render the correct UI. Now, in order to test it, we must to render all component’s dependency tree. Finally, we are going to use mount.
First, we import mount
in line 1.
Next, we create a wrapperMounted
in line 12, and then return our button in line 19 using the wrapperMounted
. Now, with our component “mounted” we have access to the whole tree of our component. This way we can search for the button and even the rendered input by ElementUI.
In this case I’m also returning the wrapperMounted
and the inputMounted
as we are going to use them in the next test.
This way, we need to make our last test pass, in which we are verifying the submitted
event emission.
To do this, as we are dealing with events from the native components that are created by ElementUI, we need to import the wrapperMounted
and the inputMounted
instead of the versions on shallowMount
in line 4.
Them it is only needed to replace it on the test. This way, we go back to green.
Finally, let’s change only the VUserProfile.vue
css as we have already changed one of the components to use the third-party library.
// src/components/VUserProfile.vue<style scoped>
.user-profile {
border-top: solid 1px #ccc;
padding-top: 20px;
margin-top: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.user-profile__avatar {
border-radius: 50%;
width: 150px;
height: 150px;
}
.user-profile__name {
margin-top: 14px;
font-size: 24px;
font-family: 'Bungee', cursive;
text-transform: uppercase;
}
.user-profile__bio {
margin-top: 14px;
font-family: 'Open Sans', sans-serif;
}
</style>
Done! Here you are! Our application is tested and functional 😄
In this article I will not approach css modules
because it is not part of the context of this series, however it is strongly advisable to make use of modules
instead of scoped
css, you can find more information here and here.
Overview
In this fourth article, we did:
- Using a third-party component library
- We’ve updated the tests to acommodate these changes
Be aware that next week I will bring a summary of everything, along with all the thanks and conciderations.
Thank you very much for your attention and I apologize again for the delay 😅
If you liked, please click on the 💚, and any questions, suggestions or corrections feel free to send me a message, I thank you very much 😄.
My Twitter: @DKuroski
See you next week 😄