michaelAwad.io

VueJS unit testing example HTTP request

...

December 20, 2020

Chances are that when you are working on a front-end application that you have to test an HTTP request. In this article, I’ll share a template for unit testing an HTTP call in VueJS using chai.

For this article, I’m assuming you have your VueJS app and testing environment already set up.

VueJS unit testing example HTTP request

Setup mock data

To set up the mock environment we first need to know what we are testing:

export default {
  name: 'myComponent',
  data () {
    return {
      mockDataItems: []
    }
  },
  methods: {
    getDataFromMyApi() {
      this.$http.get('/mock-data').then(response => {
        this.mockDataItems = response.body
      }, response => {
        this.errorMessage = response.error
      })
    }
  }
}

Our VueJS component

First define a mock response, since we are not using TypeScript make sure it matches the data structure of the real response, don’t forget the data resides in the body. Also, the response resembles a Promise, with this we can control the flow of the test.

For the happy flow we will create the following mock response:

  const responseSuccess = Promise.resolve({ body: ['myMockDataItem 1', 'myMockDataItem 1'] })

For te unhappy flow we create the following mock response:

  const responseFailed = Promise.reject({ error: 'The request failed' })

Testing the HTTP call

In our test we don’t want to trigger the real HTTP call, however, our component expects the same function. This is where we mock the HTTP get function, to mimic the behavior of the real HTTP call. To use the mock function we created, we need to invoke it in our test. When the function is invoked we can expect on it.

Testing the happy path

For the happy path, we want to resolve the promise so we return the resolved promise from the mock response we defined earlier in the article.

  const myComponent = shallow(myComponent, {
    mocks: {
      $http: {
        get: () => responseSuccess
      }
    }
  })

In this case, I would like to check if the response data is assigned to the mockDataItems data attribute.

it('does succesfull http call', () => {

  myComponent.vm.getDataFromMyApi()
  
  return response.then(() => {
    expect(myComponent.vm.mockDataItems).to.deep.equal(['myMockDataItem 1', 'myMockDataItem 1'])
  })
})

Test the unhappy path

For the unhappy path, we want to reject the promise so we return the rejected promise from the mock response:

  const myComponent = shallow(myComponent, {
    mocks: {
      $http: {
        get: () => responseFailed
      }
    }
  })

In this case, I would like the check of the response error message is assigned to the errorMessage data attribute:

it('does unsuccesfull http call', () => {

  myComponent.vm.getDataFromMyApi()
  
  return response.then(() => {
    expect(myComponent.vm.errorMessage).to.deep.equal('The request failed')
  })
})

Conclusion

The official documentation out there is minimal on how to unit test an HTTP call in VueJS. With this article, I want to give some clarity, as you can see it is not that difficult and very straight forward. In this article we discussed:

  • How to unit test an HTTP get request
  • Testing the happy path and the unhappy path.

We only covered the HTTP get request, however, the same logic applies to all other HTTP requests(GET, PUT, POST) and you will be able to test them the same way.

Below you can find the complete code for both happy and unhappy path.

Happy coding!

The complete code

import { shallow } from 'vue-test-utils'
import { expect } from 'chai'
import myComponent from './myComponent'
  
it('does succesfull http call', () => {
    const responseSuccess = Promise.resolve({ body: ['myMockDataItem 1', 'myMockDataItem 1'] })
    const myComponent = shallow(myComponent, {
        mocks: {
            $http: {
                get: () => responseSuccess
            }
        }
    })

    myComponent.vm.getDataFromMyApi()
  
    return response.then(() => {
        expect(myComponent.vm.mockDataItems).to.deep.equal(['myMockDataItem 1', 'myMockDataItem 1'])
  })

  it('does unsuccesfull http call', () => {
    const responseFailed = Promise.reject({ error: 'The request failed' })
    const myComponent = shallow(myComponent, {
        mocks: {
            $http: {
                get: () => responseFailed
            }
        }
    })

    myComponent.vm.getDataFromMyApi()
  
    return response.then(() => {
        expect(myComponent.vm.errorMessage).to.deep.equal('The request failed')
  })
})

Michael Awad

I'm fascinated by the power of a strong mindset. I combine this with being a web developer, which keeps me motivated. But how, you may ask? That's what I share on this website. For more information about me personally, check out the about me page: About Me

Are you enjoying this blog and do you want to receive these articles straight into your inbox? Enter your e-mail below and hit the subscribe button!



I won't send you spam and you can unsubscribe at any time