Unit testing jQuery getJSON function errors with the fail method, using Jasmine and Karma

老子叫甜甜 提交于 2019-12-13 20:21:41

问题


I've written a unit test for a function that calls the jQuery getJSON method. The only thing that I'm testing is that it is called with the expected URL. My unit test uses a Jasmine Spy to mock the API call. However, when I run my unit tests I get this error:

1) should make a request to the expected URL when running on localhost
     test module getDataFromApi function
     TypeError: Cannot read property 'fail' of undefined

In my unit test I've created a Jasmine Spy, which returns the done and fail methods. What am I doing wrong here?

Here is my unit test:

describe('getFundDataFromApi function', function () {
    beforeEach(function () {
        spyOn($, "getJSON").and.callFake(function () {
            return {
                done: function () {},
                fail: function () {}
            };
        });
    });
    it('should make a request to the expected URL when running on localhost', function () {
        var expectedUrl = '/assets/mock-data/mock-data.json';
        module.getDataFromApi();
        expect($.getJSON).toHaveBeenCalled();
        expect($.getJSON).toHaveBeenCalledWith({url:expectedUrl});
    });
});

Function I'm trying to test: getDataFromApi

getDataFromApi: function () {
    var mod = this;
    var url = this.settings.apiUrl;

    $.getJSON({
        url: url
    })
    .done(function (data) {
        mod.processApiData(data);
    })
    .fail(function () {
        mod.displayErrorMessage();
    });
},

回答1:


In your function getDataFromApi you are chaining the call of fail after done but, in the mocked version of done, it returns nothing(undefined), so, you get TypeError: Cannot read property 'fail' of undefined.

You can make the done function to return an object with a fail property that is a function.

beforeEach(function() {
  spyOn($, "getJSON").and.callFake(function() {
    return {
      done: function() {
        return { fail: function() {} };
      }
    };
  });
});

Or, one line ES6 version
spyOn($, "getJSON").and.callFake(() => ({ done: () => ({fail: () => {}}) }));

Or, if you are planning to do more in your tests, like testing success or failed responses, probably returning a jQuery Deferred can help you

beforeEach(function() {
  spyOn($, "getJSON").and.callFake(function() {
    const deferred = $.Deferred();

    deferred.resolve({'success': true});

    return deferred;
  });
});

Calling deferred.reject({'success': false}); will give you the chance to test for errors.

Hope it helps



来源:https://stackoverflow.com/questions/53392072/unit-testing-jquery-getjson-function-errors-with-the-fail-method-using-jasmine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!