如何正确使用模拟ajax库与Jasmine

时间:2014-01-24 10:58:49

标签: javascript jquery jasmine jasmine-ajax

我有一个调用JSON的函数,然后在success函数中对DOM进行一些更改。我正在尝试在我的Jasmine测试中使用mock-ajax library,以避免暴露各种私有函数进行模拟。

即使在单步执行测试时设置了request.response,也永远不会调用onSuccess方法。

我的测试:

 describe('the table loader', function () {
        var request;

        beforeEach(function() {
            //html with a loader div, an output div and a transit and dwell template
            setFixtures('<div class="loader"></div><div class="row"><div id="output" class="col-xs-12"></div></div><script id="thingTemplate" type="text/x-handlebars">{{snip}}</script>');
            expect($('.loader')).toBeVisible();

            //start ajax call
            window.dashboards.thing.display({
                loaderId: '.loader',
                templateId: '#thingTemplate',
                templateOutletId: '#output',
                dataUrl: '/my/fake/url'
            });
            //catch the ajax request
            request = mostRecentAjaxRequest();
        });

        describe('on success', function () {
            beforeEach(function() {
                //populate the response
                request.response({
                    status: 200,
                    responseText: "{rowItem: [{},{},{}]}"
                });
            });

            it('should hide the loader', function () {
                //thing should now receive that JSON and act accordingly
                expect($('.loader')).not.toBeVisible();
            });
        });
    });

和我的代码:

(function (dashboards, $) {
    dashboards.thing = dashboards.thing || {};

    var compileTable = function(templateId, jsonContext) {
        var source = $(templateId).html();
        var template = Handlebars.compile(source);
        var context = jsonContext;
        return template(context);
    };

    var getDashboardData = function(options) {
        $.getJSON(
            options.dataUrl,
            function (data) {
                processDashboardData(options, data);
            }
        ).fail(function (jqxhr, textStatus, error) {
            console.log('error downloading dashboard data');
            console.log(textStatus + ': ' + error);
        }).always(function() {
            console.log('complete');
        });
    };

    var processDashboardData = function (options, data) {
        $(options.loaderId).hide();
        $(options.templateOutletId).html(compileTable(options.templateId, data));
    };

    dashboards.thing.display = function (options) {
        getDashboardData(options);
    };
}(
    window.dashboards = window.dashboards || {},
    jQuery
));

没有调用延迟函数(成功,错误和始终)。

修改

基于@ gregg的答案(并且他是对的,我没有在示例代码中包含UseMock调用)这感觉就像版本问题。即使有这个电话,这仍然不适合我。

我添加了runnable example on github

3 个答案:

答案 0 :(得分:1)

您需要确保在实际进行调用之前使用jasmine.Ajax.useMock()安装ajax模拟,否则jasmine-ajax将不会接管XHR对象并且您将发出实际请求。一旦我针对您的示例代码执行了此操作,看起来您发送的responseText不是JSON可解析的并且jQuery会爆炸。但我仍然看到我的控制台中记录了“完整”消息。

答案 1 :(得分:1)

因此,截至2014年1月29日,1.3.1标记中Github上的mock-ajax自述文件中的下载链接未指向该文件的正确版本。

从标签的lib文件夹手动下载mock-ajax文件确实有效。

换句话说,对于1.3.1标记版本,请勿从the readme link下载the tag lib folder directly下载

答案 2 :(得分:0)

你的ajax调用和jasmine返回的数据格式可能不同 - 我相信会抛出一个无法恢复的异常,因此你的回调函数都没有运行。

较新版本的jasmine-ajax也使用request.respondWith,它也是值得注意的(虽然我认为jQuery处理这个),Jasmine没有定义XMLHttpRequest.Done,所以如果你使用vanilla JS你必须自己处理这个案子。最后,我使用的是jasmine.Ajax.install()而不是jasmine.Ajax.useMock()

哇 - 很难知道究竟要做什么,因为Jasmine对旧版本的文档很差,而且它们之间存在很多不一致的地方。