vue.jsunit-testingvuejs3spy

Vue Js - mock the $http request using sinon modules


In VueJs project I have list of api request methods in apiList.ts file with below code. Also I am trying to add the unit test case for getUsers, addUser, updateUser methods but unable to mock the http methods(get/post/put). Could someone help to add the test case for this below code.

File: apiList.ts

import Vue from 'vue';

export const API_LISTS = {
    getUsers: () => {
        const apiUrl = `/get/users`;
        return Vue.prototype.$http.get(apiUrl);
    },
    addUser: (requestData: any) => {        
        let apiUrl = `/new/user`;
        return Vue.prototype.$http.post(apiUrl, requestData);
    },
    updateUser: (requestData: any) => {
        const url = `/update/user`;
        return Vue.prototype.$http.put(url, requestData);
    },
}

File: apiLists.spec.ts

    import { assert } from 'chai';
    import {API_LISTS } from 'apiList';
    
    describe.only('getUsers', () => {
    console.log("---------------------------------step-1");
    let axiosGetStub: any;
    const responseData = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }];

    beforeEach(() => {
        console.log("---------------------------------step-2");
        axiosGetStub = sinon.stub(Vue.prototype.$http, 'get').callsFake(() => Promise.resolve({ status: 200, data: responseData }));
        console.log("---------------------------------step-3");
    });

    afterEach(() => {
        console.log("---------------------------------step-4");
        axiosGetStub.restore();
    });

    it('should call $http.get with the correct endpoint', async () => {
        console.log("---------------------------------step-5");
        await API_LISTS.getUsers();
        expect(axiosGetStub.calledOnce).equal(true);
        // expect(axiosGetStub.calledWith('/users')).equal(true);
    });

    it('should return the response data', async () => {
        console.log("---------------------------------step-6");
        const result = await API_LISTS.getUsers();
        console.log("---------------------------------step-7");
        // expect(result).equal(responseData);
    });
});

Output: I am getting the logs step1, step2, step4 but step3, step5, step6 and step7 not getting.

enter image description here


Solution

  • In my opinion: first i install chai and sinon with npm

    npm install chai sinon --save-dev
    

    after that i create a mock for http on before()

    // Create a mock for $http
    $httpMock = {
      get: sinon.stub(),
      post: sinon.stub(),
      put: sinon.stub(),
    };
    
    // Assign the mock to Vue.prototype.$http
    Vue.prototype.$http = $httpMock;
    

    And on beforeEach() reset the stbs before each test

    $httpMock.get.reset();
    $httpMock.post.reset();
    $httpMock.put.reset();
    

    After that you do this

    it('API_LISTS.getUsers - should call $http.get with the correct URL', () => {
    const expectedUrl = '/get/users';
    
    // Invoke the getUsers method
    API_LISTS.getUsers();
    
    // Assert that $http.get was called with the expected URL
    assert.isTrue($httpMock.get.calledOnceWith(expectedUrl));
    });
    
    it('API_LISTS.addUser - should call $http.post with the correct URL and data', () => {
    const expectedUrl = '/new/user';
    const requestData = { name: 'John', age: 25 };
    
    // Invoke the addUser method
    API_LISTS.addUser(requestData);
    
    // Assert that $http.post was called with the expected URL and data
    assert.isTrue($httpMock.post.calledOnceWith(expectedUrl, requestData));
    });
    
    it('API_LISTS.updateUser - should call $http.put with the correct URL and data', () => {
    const expectedUrl = '/update/user';
    const requestData = { id: 1, name: 'John' };
    
    // Invoke the updateUser method
    API_LISTS.updateUser(requestData);
    
    // Assert that $http.put was called with the expected URL and data
    assert.isTrue($httpMock.put.calledOnceWith(expectedUrl, requestData));
    });
    

    Good luck for you