Search code examples
unit-testingkarma-runnervue.jsvue-resource

State not changing when unit testing VueJS and VueResource


I'm trying to test a service that I've created that makes an API call with vue-resource. The service should make the call and update the component with the new data, however in my tests it doesn't register the updated value. I'm using the same setup as the vue-cli webpack example and have based my auth service off this repo (which unfortunately doesn't have any tests)

my service:

export default {
   login(context, creds){
      context.$http.post(LOGIN_URL, creds)
        .then((response) => {
           //do something else here
        }, (response) => {
           context.error = response.data.error
        }
   }
}

my test:

import Vue from 'vue'
import VueResource from 'vue-resource'
Vue.use(VueResource)
import Auth from 'src/auth'

describe('Auth', () => {
   it('should throw an error on unsuccessful login', (done) => {

     //intercept the api call and force an invalid response
     Vue.http.interceptors.unshift((request, next) => {
        next(request.respondWidth({error: 'some error'}, {status: 401}));
     });


     const vm = new Vue({
        data: {
           error: ''
        }
     }).$mount()

     Auth.login(vm, {email: '[email protected]', pass: 'test'} )

     //this always fails
     expect(vm.error).to.equal('some error')

     //ive also tried:
     vm.$nextTick(() => {
        expect(vm.error).to.equal('some error')
        //done()
     });

     //undo our interceptor
     Vue.http.interceptors.shift()

   }
}

When I run the test it fails because it's expecting '' to equal 'some error'.

My suspicions are around the fact that vue-resource is using promises.


Solution

  • After reading through some of the Vue.js tests I found my answer. Instead of using vm.$nextTick I did the following:

    setTimeout(function(){
       expect(vm.error).to.equal('something')
       done()
    }, 0)