SlideShare a Scribd company logo
Unit Tests
In
Tappero Gregory
2016 - WyzAnt.
Tooling.
{
"karma-mocha": "^0.2.1",
"karma-chai": "^0.1.0",
"karma-chai-as-promised": "^0.1.2",
"karma-sinon": "^1.0.4",
"karma-sinon-chai": "^1.2.0",
"karma-sinon-stub-promise": "^1.0.0",
"whatwg-fetch": "^0.11.0"
"fetch-mock": "^4.1.0",
}
Testing a filter.
import { prettybytes } from 'src/filters';
describe('Filter "prettybytes".', () => {
it('Prettybytes shows the right KB, MB, GB, TB unit.', () => {
expect(prettybytes(1024)).to.equal('1 KB');
expect(prettybytes(1048576)).to.equal('1 MB');
expect(prettybytes(1048576*1024)).to.equal('1 GB');
expect(prettybytes(1048576*1048576)).to.equal('1 TB');
expect(prettybytes(230)).to.equal('230 Bytes');
});
});
Testing an API call, mocking fetch.
import { authentify } from 'src/store/actions/auth';
import fetchMock from 'fetch-mock';
import { fetchUserToken } from 'src/api/web';
describe('Authentify action', () => {
let sandbox;
beforeEach(() => {
sandbox = sinon.sandbox.create();
});
afterEach(() => {
sandbox.restore();
fetchMock.restore();
});
it('FetchUserToken should eventually resolve with a token.', () => {
fetchMock.mock('/login/getaccesstoken/', { Model: ' ' });
return fetchUserToken().should.eventually.equal(' ');
});
});
Testing a component (1/2).
import Vue from 'vue';
import FinalCountdown from 'src/components/workflow/FinalCountdown';
describe('workflow/FinalCountDown component.', () => {
const getComponent = (date) => {
let vm = new Vue({
template: '<div><final-countdown v-ref:component :date="date"></final-countdown></div>',
components: {
FinalCountdown
},
data: {
date
}
});
return vm;
};
...
Testing a component (2/2).
it('Should render correctly with a date in the future.', () => {
const tomorrow = new Date(new Date().getTime() + 24 * 60 * 60 * 1000);
const vm = getComponent(tomorrow).$mount();
expect(vm.$el).to.be.ok;
// Counter should show 23:59:59
// timeUntilExpiration is a component method.
expect(vm.$refs.component.timeUntilExpiration()).to.equal('23:59:59');
// Priority should be normal.
expect(vm.$refs.component.priorityLevel()).to.equal('normal');
});
Testing a component property change.
it('Should be valid only when a radio option is selected.', () => {
const vm = getComponent('Bob').$mount();
const component = vm.$refs.component;
expect(component.isFormValid).to.be.false;
component.picked = 3;
component.$nextTick(() => {
expect(component.isFormValid).to.be.true;
});
});
Testing a component event.
it('Send should dispatch "declinedWorkflowTask" with the choice payload.', () => {
const vm = getComponent('Bob').$mount();
const component = vm.$refs.component;
let spy = sinon.spy();
vm.$on('declinedWorkflowTask', spy);
component.sendReply();
expect(spy).to.have.been.calledWith({
choice: null,
text: ''
});
});
Testing a component ready() hook.
it('Should focus on textarea when ready.', (done) => {
const vm = getComponent();
const component = vm.$refs.component;
// Action triggered by Message Template child component.
fetchMock.mock('/tutor/templates', [{ title: 'template A', body: 'AAA' },
{ title: 'template B', body: 'BBB' }]);
// Triggers ready() on our component.
vm.$appendTo(document.body);
component.$nextTick(() => {
expect(document.activeElement).to.equal(component.$els.textarea);
done();
})
});
Testing with a Vuex store.
import store from 'src/store';
describe('workflow/WorkflowAccept component.', () => {
// Update store states here or import from fixtures.
store.state.availability = { … };
const getComponent = () => {
let vm = new Vue({
template: '<div><workflow-accept v-ref:component></workflow-accept></div>',
components: {
WorkflowAccept
},
// Inject store here.
store: store
});
return vm.$mount();
};
Testing a Vuex action (1/2).
import { sendInitialDirectContactResponse } from 'src/store/actions/workflow';
import store from 'src/store';
const state = store.state;
import { testAction } from './helper';
describe('sendInitialDirectContactResponse action.', () => {
beforeEach(() => {
state.workflow.workflowTask = {
id: 1,
conversationThread: {
id: 2,
},
initialDirectContact: {
id: 3,
},
};
...
});
Testing a Vuex action (2/2).
it('Should dispatch the right mutations.', (done) => {
testAction(sendInitialDirectContactResponse, [1, 1, 'test'], state, [
{ name: 'DELETE_WORKFLOW_TASK', payload: [1] },
{ name: 'ADD_CONVERSATION_THREAD_TO_TOP' },
{ name: 'UPDATE_CONVERSATION_THREAD' },
], done);
});
it('Should not dispatch ADD_CONVERSATION_THREAD_TO_TOP if ...', (done) => {
state.app.menuSelection = 'archived';
testAction(sendInitialDirectContactResponse, [1, 1, 'test'], state, [
{ name: 'DELETE_WORKFLOW_TASK', payload: [1] },
], done);
});
Testing a Vuex action - testaction.js (1/2).
// Helper for testing action with expected mutations.
export function testAction(action, args, state, expectedMutations, done) {
let count = 0;
// mock dispatch
const dispatch = (name, ...payload) => {
const mutation = expectedMutations[count];
expect(mutation.name).to.equal(name);
// if our mutation has a payload and our expected mutation
// wants us to assert this payload.
if (payload && mutation.payload) {
expect(mutation.payload).to.deep.equal(payload);
}
count++;
if (count === expectedMutations.length) {
done();
}
Testing a Vuex action - testaction.js (2/2)
// ...
if (count > expectedMutations.length) {
// Missing non expected mutations.
// List all expected mutations!
expect(count).to.equal(expectedMutations.length);
}
}
// call the action with mocked store and arguments
action({ dispatch, state }, ...args);
// check if no mutations should have been dispatched
if (count === 0) {
expect(expectedMutations.length).to.equal(0);
done();
}
};

More Related Content

What's hot (20)

PDF
Workshop 14: AngularJS Parte III
Visual Engineering
 
PDF
Unit Testing Express and Koa Middleware in ES2015
Morris Singer
 
PDF
The JavaFX Ecosystem
Andres Almiray
 
PDF
Intro to testing Javascript with jasmine
Timothy Oxley
 
PDF
Workshop 12: AngularJS Parte I
Visual Engineering
 
PPTX
Rapid prototyping and easy testing with ember cli mirage
Krzysztof Bialek
 
PPTX
Building Progressive Web Apps for Windows devices
Windows Developer
 
PDF
Containers & Dependency in Ember.js
Matthew Beale
 
PPTX
Effective C++/WinRT for UWP and Win32
Windows Developer
 
PDF
Testing Ember Apps: Managing Dependency
Matthew Beale
 
PDF
Building scalable applications with angular js
Andrew Alpert
 
PDF
The Road to Native Web Components
Mike North
 
PPTX
Good karma: UX Patterns and Unit Testing in Angular with Karma
ExoLeaders.com
 
PDF
Developing Modern Java Web Applications with Java EE 7 and AngularJS
Shekhar Gulati
 
PDF
Ember testing internals with ember cli
Cory Forsyth
 
PPTX
Full Stack Unit Testing
GlobalLogic Ukraine
 
PDF
Introduction to AngularJS For WordPress Developers
Caldera Labs
 
PDF
Future of Web Apps: Google Gears
dion
 
PPTX
Express JS
Designveloper
 
PDF
Redux vs Alt
Uldis Sturms
 
Workshop 14: AngularJS Parte III
Visual Engineering
 
Unit Testing Express and Koa Middleware in ES2015
Morris Singer
 
The JavaFX Ecosystem
Andres Almiray
 
Intro to testing Javascript with jasmine
Timothy Oxley
 
Workshop 12: AngularJS Parte I
Visual Engineering
 
Rapid prototyping and easy testing with ember cli mirage
Krzysztof Bialek
 
Building Progressive Web Apps for Windows devices
Windows Developer
 
Containers & Dependency in Ember.js
Matthew Beale
 
Effective C++/WinRT for UWP and Win32
Windows Developer
 
Testing Ember Apps: Managing Dependency
Matthew Beale
 
Building scalable applications with angular js
Andrew Alpert
 
The Road to Native Web Components
Mike North
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
ExoLeaders.com
 
Developing Modern Java Web Applications with Java EE 7 and AngularJS
Shekhar Gulati
 
Ember testing internals with ember cli
Cory Forsyth
 
Full Stack Unit Testing
GlobalLogic Ukraine
 
Introduction to AngularJS For WordPress Developers
Caldera Labs
 
Future of Web Apps: Google Gears
dion
 
Express JS
Designveloper
 
Redux vs Alt
Uldis Sturms
 

Viewers also liked (20)

PDF
Gui Input Tools for Math [UKMC09]
Greg TAPPERO
 
PDF
第一次用 Vue.js 就愛上 [改]
Kuro Hsu
 
PDF
Vue js 大型專案架構
Hina Chen
 
PPTX
Vue 2.0 + Vuex Router & Vuex at Vue.js
Takuya Tejima
 
ODP
An Introduction to Vuejs
Paddy Lock
 
PDF
VueJS: The Simple Revolution
Rafael Casuso Romate
 
PPTX
How tovuejs
Daniel Chou
 
PPTX
VueJS - Uma alternativa elegante
Jonathan Bijos
 
PDF
VueJs 簡介
Jocelyn Hsu
 
PPTX
Vuejs Angularjs e Reactjs. Veja as diferenças de cada framework!
José Barbosa
 
PDF
Agile Planning
Nikita Filippov
 
PPT
Эволюция Скрама в «Моём Круге»
Evgeny Kuryshev
 
PDF
VueJS meetup (Basics) @ nodum.io
Wietse Wind
 
PDF
Stop Making Excuses and Start Testing Your JavaScript
Ryan Anklam
 
PDF
nodum.io MongoDB Meetup (Dutch)
Wietse Wind
 
PDF
Automated Testing in EmberJS
Ben Limmer
 
PPTX
PHP 5.6 New and Deprecated Features
Mark Niebergall
 
PDF
действуй опираясь на ценности а не просто применяй инструменты максим цепков
Maxim Tsepkov
 
PDF
Advanced QUnit - Front-End JavaScript Unit Testing
Lars Thorup
 
PPTX
Qunit Java script Un
akanksha arora
 
Gui Input Tools for Math [UKMC09]
Greg TAPPERO
 
第一次用 Vue.js 就愛上 [改]
Kuro Hsu
 
Vue js 大型專案架構
Hina Chen
 
Vue 2.0 + Vuex Router & Vuex at Vue.js
Takuya Tejima
 
An Introduction to Vuejs
Paddy Lock
 
VueJS: The Simple Revolution
Rafael Casuso Romate
 
How tovuejs
Daniel Chou
 
VueJS - Uma alternativa elegante
Jonathan Bijos
 
VueJs 簡介
Jocelyn Hsu
 
Vuejs Angularjs e Reactjs. Veja as diferenças de cada framework!
José Barbosa
 
Agile Planning
Nikita Filippov
 
Эволюция Скрама в «Моём Круге»
Evgeny Kuryshev
 
VueJS meetup (Basics) @ nodum.io
Wietse Wind
 
Stop Making Excuses and Start Testing Your JavaScript
Ryan Anklam
 
nodum.io MongoDB Meetup (Dutch)
Wietse Wind
 
Automated Testing in EmberJS
Ben Limmer
 
PHP 5.6 New and Deprecated Features
Mark Niebergall
 
действуй опираясь на ценности а не просто применяй инструменты максим цепков
Maxim Tsepkov
 
Advanced QUnit - Front-End JavaScript Unit Testing
Lars Thorup
 
Qunit Java script Un
akanksha arora
 
Ad

Similar to Vuejs testing (20)

PDF
Chaining and function composition with lodash / underscore
Nicolas Carlo
 
PDF
Chaining et composition de fonctions avec lodash / underscore
Nicolas Carlo
 
PPTX
Build Lightweight Web Module
Morgan Cheng
 
PDF
Service worker: discover the next web game changer
Sandro Paganotti
 
PDF
Source Code for Dpilot
Nidhi Chauhan
 
PDF
Dpilot - Source Code with Snapshots
Kritika Phulli
 
PDF
Dpilot Source Code With ScreenShots
DeepAnshu Sharma
 
PDF
Advanced redux
Boris Dinkevich
 
PDF
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
PHP Conference Argentina
 
PDF
High Performance Core Data
Matthew Morey
 
PPTX
Nevermore Unit Testing
Ihsan Fauzi Rahman
 
PPTX
ES6 Overview
Bruno Scopelliti
 
PDF
Writing native bindings to node.js in C++
nsm.nikhil
 
PDF
Reduxing like a pro
Boris Dinkevich
 
PDF
JJUG CCC 2011 Spring
Kiyotaka Oku
 
PDF
G*ワークショップ in 仙台 Grails(とことん)入門
Tsuyoshi Yamamoto
 
PDF
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Morocco 2019
Matt Raible
 
KEY
Integrating Wicket with Java EE 6
Michael Plöd
 
PDF
Testowanie JavaScript
Tomasz Bak
 
PDF
Varnish Enterprise - when you need the full power of caching
Thijs Feryn
 
Chaining and function composition with lodash / underscore
Nicolas Carlo
 
Chaining et composition de fonctions avec lodash / underscore
Nicolas Carlo
 
Build Lightweight Web Module
Morgan Cheng
 
Service worker: discover the next web game changer
Sandro Paganotti
 
Source Code for Dpilot
Nidhi Chauhan
 
Dpilot - Source Code with Snapshots
Kritika Phulli
 
Dpilot Source Code With ScreenShots
DeepAnshu Sharma
 
Advanced redux
Boris Dinkevich
 
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
PHP Conference Argentina
 
High Performance Core Data
Matthew Morey
 
Nevermore Unit Testing
Ihsan Fauzi Rahman
 
ES6 Overview
Bruno Scopelliti
 
Writing native bindings to node.js in C++
nsm.nikhil
 
Reduxing like a pro
Boris Dinkevich
 
JJUG CCC 2011 Spring
Kiyotaka Oku
 
G*ワークショップ in 仙台 Grails(とことん)入門
Tsuyoshi Yamamoto
 
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Morocco 2019
Matt Raible
 
Integrating Wicket with Java EE 6
Michael Plöd
 
Testowanie JavaScript
Tomasz Bak
 
Varnish Enterprise - when you need the full power of caching
Thijs Feryn
 
Ad

Recently uploaded (20)

PPTX
MailsDaddy Outlook OST to PST converter.pptx
abhishekdutt366
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PPTX
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PDF
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
PDF
Efficient, Automated Claims Processing Software for Insurers
Insurance Tech Services
 
PDF
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
PPTX
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
PDF
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
PPTX
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
DOCX
Import Data Form Excel to Tally Services
Tally xperts
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
PPTX
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
PDF
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
PDF
Understanding the Need for Systemic Change in Open Source Through Intersectio...
Imma Valls Bernaus
 
PDF
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
PDF
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
PPTX
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PPTX
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 
MailsDaddy Outlook OST to PST converter.pptx
abhishekdutt366
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
Efficient, Automated Claims Processing Software for Insurers
Insurance Tech Services
 
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
Import Data Form Excel to Tally Services
Tally xperts
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
Understanding the Need for Systemic Change in Open Source Through Intersectio...
Imma Valls Bernaus
 
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 

Vuejs testing

  • 2. Tooling. { "karma-mocha": "^0.2.1", "karma-chai": "^0.1.0", "karma-chai-as-promised": "^0.1.2", "karma-sinon": "^1.0.4", "karma-sinon-chai": "^1.2.0", "karma-sinon-stub-promise": "^1.0.0", "whatwg-fetch": "^0.11.0" "fetch-mock": "^4.1.0", }
  • 3. Testing a filter. import { prettybytes } from 'src/filters'; describe('Filter "prettybytes".', () => { it('Prettybytes shows the right KB, MB, GB, TB unit.', () => { expect(prettybytes(1024)).to.equal('1 KB'); expect(prettybytes(1048576)).to.equal('1 MB'); expect(prettybytes(1048576*1024)).to.equal('1 GB'); expect(prettybytes(1048576*1048576)).to.equal('1 TB'); expect(prettybytes(230)).to.equal('230 Bytes'); }); });
  • 4. Testing an API call, mocking fetch. import { authentify } from 'src/store/actions/auth'; import fetchMock from 'fetch-mock'; import { fetchUserToken } from 'src/api/web'; describe('Authentify action', () => { let sandbox; beforeEach(() => { sandbox = sinon.sandbox.create(); }); afterEach(() => { sandbox.restore(); fetchMock.restore(); }); it('FetchUserToken should eventually resolve with a token.', () => { fetchMock.mock('/login/getaccesstoken/', { Model: ' ' }); return fetchUserToken().should.eventually.equal(' '); }); });
  • 5. Testing a component (1/2). import Vue from 'vue'; import FinalCountdown from 'src/components/workflow/FinalCountdown'; describe('workflow/FinalCountDown component.', () => { const getComponent = (date) => { let vm = new Vue({ template: '<div><final-countdown v-ref:component :date="date"></final-countdown></div>', components: { FinalCountdown }, data: { date } }); return vm; }; ...
  • 6. Testing a component (2/2). it('Should render correctly with a date in the future.', () => { const tomorrow = new Date(new Date().getTime() + 24 * 60 * 60 * 1000); const vm = getComponent(tomorrow).$mount(); expect(vm.$el).to.be.ok; // Counter should show 23:59:59 // timeUntilExpiration is a component method. expect(vm.$refs.component.timeUntilExpiration()).to.equal('23:59:59'); // Priority should be normal. expect(vm.$refs.component.priorityLevel()).to.equal('normal'); });
  • 7. Testing a component property change. it('Should be valid only when a radio option is selected.', () => { const vm = getComponent('Bob').$mount(); const component = vm.$refs.component; expect(component.isFormValid).to.be.false; component.picked = 3; component.$nextTick(() => { expect(component.isFormValid).to.be.true; }); });
  • 8. Testing a component event. it('Send should dispatch "declinedWorkflowTask" with the choice payload.', () => { const vm = getComponent('Bob').$mount(); const component = vm.$refs.component; let spy = sinon.spy(); vm.$on('declinedWorkflowTask', spy); component.sendReply(); expect(spy).to.have.been.calledWith({ choice: null, text: '' }); });
  • 9. Testing a component ready() hook. it('Should focus on textarea when ready.', (done) => { const vm = getComponent(); const component = vm.$refs.component; // Action triggered by Message Template child component. fetchMock.mock('/tutor/templates', [{ title: 'template A', body: 'AAA' }, { title: 'template B', body: 'BBB' }]); // Triggers ready() on our component. vm.$appendTo(document.body); component.$nextTick(() => { expect(document.activeElement).to.equal(component.$els.textarea); done(); }) });
  • 10. Testing with a Vuex store. import store from 'src/store'; describe('workflow/WorkflowAccept component.', () => { // Update store states here or import from fixtures. store.state.availability = { … }; const getComponent = () => { let vm = new Vue({ template: '<div><workflow-accept v-ref:component></workflow-accept></div>', components: { WorkflowAccept }, // Inject store here. store: store }); return vm.$mount(); };
  • 11. Testing a Vuex action (1/2). import { sendInitialDirectContactResponse } from 'src/store/actions/workflow'; import store from 'src/store'; const state = store.state; import { testAction } from './helper'; describe('sendInitialDirectContactResponse action.', () => { beforeEach(() => { state.workflow.workflowTask = { id: 1, conversationThread: { id: 2, }, initialDirectContact: { id: 3, }, }; ... });
  • 12. Testing a Vuex action (2/2). it('Should dispatch the right mutations.', (done) => { testAction(sendInitialDirectContactResponse, [1, 1, 'test'], state, [ { name: 'DELETE_WORKFLOW_TASK', payload: [1] }, { name: 'ADD_CONVERSATION_THREAD_TO_TOP' }, { name: 'UPDATE_CONVERSATION_THREAD' }, ], done); }); it('Should not dispatch ADD_CONVERSATION_THREAD_TO_TOP if ...', (done) => { state.app.menuSelection = 'archived'; testAction(sendInitialDirectContactResponse, [1, 1, 'test'], state, [ { name: 'DELETE_WORKFLOW_TASK', payload: [1] }, ], done); });
  • 13. Testing a Vuex action - testaction.js (1/2). // Helper for testing action with expected mutations. export function testAction(action, args, state, expectedMutations, done) { let count = 0; // mock dispatch const dispatch = (name, ...payload) => { const mutation = expectedMutations[count]; expect(mutation.name).to.equal(name); // if our mutation has a payload and our expected mutation // wants us to assert this payload. if (payload && mutation.payload) { expect(mutation.payload).to.deep.equal(payload); } count++; if (count === expectedMutations.length) { done(); }
  • 14. Testing a Vuex action - testaction.js (2/2) // ... if (count > expectedMutations.length) { // Missing non expected mutations. // List all expected mutations! expect(count).to.equal(expectedMutations.length); } } // call the action with mocked store and arguments action({ dispatch, state }, ...args); // check if no mutations should have been dispatched if (count === 0) { expect(expectedMutations.length).to.equal(0); done(); } };