Writing unit tests for our Pomodoro application

Ok! Let's move to our Pomodoro application! By the way, when was the last time you took a break? Probably, it is time to open the application in your browser, wait a few minutes of the Pomodoro working period timer, and check for some kittens.

I just did it and it made me feel really nice and cute:

Writing unit tests for our Pomodoro application

I'm not your clothes... please have some rest

Let's start with mutations. Open the code in the chapter7/pomodoro folder. Open the mutations.js file and check what is happening out there. There are four mutations happening: START, STOP, PAUSE, and TOGGLE_SOUND. Guess which one we will start with. Yes, you are right, we will start with the start method. Create a vuex subfolder inside the test/unit/specs folder and add the mutations.spec.js file. Let's bootstrap it to be ready for tests:

// mutations.spec.js 
import Vue from 'vue' 
import mutations from 'src/vuex/mutations' 
import * as types from 'src/vuex/mutation_types' 
 
describe('mutations', () => { 
  var state 
 
  beforeEach(() => { 
    state = {} 
    // let's mock Vue noise plugin 
    //to be able to listen on its methods 
    Vue.noise = { 
      start: () => {}, 
      stop: () => {}, 
      pause: () => {} 
    } 
    sinon.spy(Vue.noise, 'start') 
    sinon.spy(Vue.noise, 'pause') 
    sinon.spy(Vue.noise, 'stop') 
  }) 
 
  afterEach(() => { 
    Vue.noise.start.restore() 
    Vue.noise.pause.restore() 
    Vue.noise.stop.restore() 
  }) 
 
  describe('START', () => { 
  }) 
}) 

Note that I mocked all the methods of the noise generator plugin. This is because in this spec, we don't need to test the plugin's functionality (in fact, we must do it in the scope of the plugin itself before publishing it). For the scope of this test, we should test that the plugin's methods are called when they need to be called.

In order to be able to test the start method, let's think what should happen. After the start button is clicked, we know that the application's started, paused, and stopped states must gain some specific values (actually, true, false, and false, respectively). We also know the application's interval should be started. We also know that if the Pomodoro's state is working and if the sound is enabled, the start method of the noise generator plugin should be called. In fact, this is what our method is actually doing:

[types.START] (state) { 
  state.started = true 
  state.paused = false 
  state.stopped = false 
  state.interval = setInterval(() => tick(state), 1000) 
  if (state.isWorking && state.soundEnabled) { 
    Vue.noise.start() 
  } 
}, 

But even if it didn't do all these things and we have written the test to test it, we would immediately understand that something is missing in our code and fix it. Let's then write our test. Let's start by defining the it() method that tests that all the properties were correctly set. In order to be sure that they are not already set before calling the method, let's also assert that all these properties are not defined at the start of the test:

it('should set all the state properties correctly after start', () => { 
  // ensure that all the properties are undefined 
  // before calling the start method 
  expect(state.started).to.be.undefined 
  expect(state.stopped).to.be.undefined 
  expect(state.paused).to.be.undefined 
  expect(state.interval).to.be.undefined 
  // call the start method 
  mutations[types.START](state) 
  // check that all the properties were correctly set 
  expect(state.started).to.be.true 
  expect(state.paused).to.be.false 
  expect(state.stopped).to.be.false 
  expect(state.interval).not.to.be.undefined 
}) 

Let's now check on the Vue.noise.start method. We know that it should only be called if state.isWorking is true and state.soundEnabled is true. Let's write a positive test. In this test, we would initialize both Boolean states to true and check that the noise.start method is called:

it('should call Vue.noise.start method if both state.isWorking and state.soundEnabled are true', () => { 
  state.isWorking = true 
  state.soundEnabled = true 
  mutations[types.START](state) 
  expect(Vue.noise.start).to.have.been.called 
}) 

Let's add two negative tests for each of the states, with isWorking and soundEnabled being false:

it('should not call Vue.noise.start method if state.isWorking is not true', () => { 
  state.isWorking = false 
  state.soundEnabled = true 
  mutations[types.START](state) 
  expect(Vue.noise.start).to.not.have.been.called 
}) 
 
it('should not call Vue.noise.start method if state.soundEnabled is not true', () => { 
  state.isWorking = true 
  state.soundEnabled = false 
  mutations[types.START](state) 
  expect(Vue.noise.start).to.not.have.been.called 
}) 

Our start mutation is nicely tested! Check the final state of the code in the chapter7/pomodoro2 folder. I suggest that you now write the rest of the unit tests not only for the mutations, but also for all the store-related functions that reside in getters and actions. After that, apply the techniques to test Vue components that we just learned and test some of the components of our Pomodoro application.

At this point, we are done with unit testing!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.9.2