jquery - 如何对该 JavaScript 函数进行单元测试,包括 Ajax 调用的模拟?

标签 jquery jquery-ui unit-testing mocking qunit

如本文所示 jsFiddle ,我有一个函数“init”,它配置一个按钮,以便在单击时打开一个进度对话框并发出 Ajax 调用。我想对这段 JavaScript 代码进行单元测试(使用 QUnit ),并检查以下情况:

  1. Ajax调用成功
  2. Ajax 调用失败

我需要至少模拟 Ajax 调用和对 window.open 的调用,以及我确信的其他调用,具体取决于单元测试实现。

如何为测试这两种场景的代码编写 QUnit 单元测试?

编辑:需要测试的代码:

var statusmod = (function() {
    var spinner = $("#spinner");

    var init = function(id) {
        var progressDialog = $("#progressdialog-content").dialog({
            autoOpen: false,
            title: "Launching Status Page"
        });
        var errorDialog = $("#errordialog-content").dialog({
            autoOpen: false,
            modal: true,
            buttons: {
                "OK": function() {
                    $(this).dialog("close");
                }
            }
        });

        var btn = $("#button-status");
        btn.button().click(function() {
            spinner.show();

            progressDialog.dialog("open");

            var url = $.validator.format("/api/binid/?id={0}", id);
            // Call Web service to get binary ID
            $.ajax({
                url: url,
                dataType: "json"
            }).done(function(data) {
                window.open($.validator.format("http://status/?Page=Status&Id={0}", data.Id), target = "_newtab");
            }).fail(function(jqXHR, msg, errorThrown) {
                errorDialog.dialog("open");
            }).always(function() {
                progressDialog.dialog("close");
            });

            return false;
        });
    };

    return {
        init: init,
        _spinner: spinner
    };
}());

最佳答案

我已经成功地为成功案例编写了一个 QUnit 测试,并为失败案例编写了另一个测试,正如您从 this jsFiddle 中看到的那样。 。我受雇Mockjax伪造 Ajax 响应并模拟成功/失败条件。值得注意的是,我将 Ajax 调用配置为同步,以便我可以编写同步测试,因为我很难弄清楚如何在异步 Ajax 回调触发后运行我的测试。

我还使用Sinon.JS库来伪造依赖项并验证例如对话框已正确启动。

下面包含工作测试代码,请参阅我对被测函数的问题 (statusmod.init)。如果您认为我遗漏了某些内容,请告诉我。

var dialogSpy = null;
var windowSpy = null;
var id = "srcId";
var binId = "binId";
var url = $.validator.format("/api/binid/?id={0}", id);
var btnId = "#button-status";

module("Open status page", {
    setup: function() {
        // Allow us to run tests synchronously
        $.ajaxSetup({
            async: false
        });
        windowSpy = sinon.spy(window, "open");
        dialogSpy = sinon.spy();
        sinon.stub($.fn, "dialog", function() {
            return {
                "dialog": dialogSpy
            };
        });

        statusmod.init(id);
    },
    teardown: function() {
        windowSpy.restore();
        $.fn.dialog.restore();
        $.mockjaxClear();
        // Remove click event handler for each test
        $(btnId).unbind();
    }
});

test("Successfully open status page", function() {
    expect(4);

    $.mockjax({
        url: url,
        contentType: "text/json",
        responseText: {
            Id: binId
        }
    });

    var spinner = statusmod._spinner;
    var spinnerSpy = sinon.spy(spinner, "show");

    $(btnId).click();

    ok(spinnerSpy.calledOnce, "Spinner shown");
    ok(dialogSpy.withArgs("open").calledOnce, "Dialog opened");
    ok(dialogSpy.withArgs("close").calledOnce, "Dialog closed");
    equal(windowSpy.lastCall.args[0], $.validator.format("http://status/?Page=Status&Id={0}", binId), "Window opened");
});

test("Binary ID not found on server", function() {
    expect(3);

    $.mockjax({
        url: url,
        contentType: "text/json",
        status: 404
    });

    $(btnId).click();

    ok(dialogSpy.withArgs("open").calledTwice, "Dialogs opened");
    ok(dialogSpy.withArgs("close").calledOnce, "Progress dialog closed");
    ok(!windowSpy.called, "Window not launched");
});

关于jquery - 如何对该 JavaScript 函数进行单元测试,包括 Ajax 调用的模拟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12074913/

相关文章:

javascript - 添加前缀到文件名,javascript

python - Python Eve Web 服务的单元测试用例

javascript - enzyme .eq() 还是.index()?

php - 如何在此代码 php 中的单词之间放置 '-'?

javascript - 根据时间更改链接的 href 值

jquery - 在 Sizzle/jQuery 中选择 Id 带有冒号的元素

jquery ui - 将鼠标悬停在父元素上应该触发在子元素上向下滑动

javascript - jQuery 对话框不关闭

jQuery UI 日历显示太大,想要演示大小吗?

c# - 如何测试asp.net邮件是否被发送