Working an application in Vue.js with TDD — An extensive guide for people who have time — part 5

Testing with third party libs

Daniel Kuroski
magnetis backstage
Published in
5 min readNov 21, 2018

--

This is the fifth in a series of articles:

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 = false
new 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.

src/components/VUserSearchForm.vue

Here we have just made our first bigrefactor relating the appearance. Basically, we gave a new layout to the form part of our application:

Current application ui

Awesome! Our form looks better, but:

RED

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

tests/unit/VUserSearchForm.spec.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 ElementUIon 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 Vuexcase 😄

Now, it’s only necessary to update the snapshot and we are going to have more concise information:

RED

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?

RED

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.

tests/unit/VUserSearchForm.spec.js

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.

RED

This way, we need to make our last test pass, in which we are verifying the submitted event emission.

tests/unit/VUserSearchForm.spec.js

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.

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>
Finish =D

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

summing up

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 😄

--

--