如何使用jasmine测试json内部函数?

时间:2016-04-29 16:12:41

标签: json jasmine

这是我要测试的代码:

function loadNotification(searchOption, searchKey) {
   var url = '@URLs.API.Notifications.Past' + '?searchOption=' + searchOption + '&searchValue=' + searchKey;
   $.getJSON(url)
      .done(function (nData) {
        //some code here
      })
      .fail(function (jqXHR, status, error) {
        showError('There was an error while fetching the records. Please try after some time. (' + jqXHR.status + ':' + jqXHR.statusText + ')');
      });
}

使用 jasmine ,如何测试 json 文件是否失败?我在考虑使用 .done .fail ,但我不确定它是否可行。我对 json 了解不多。任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

在测试AJAX请求(以及类似的,获取json文件等)时,检查您的代码是否可以处理完成和失败都是一个好主意。您还应该模拟您测试的数据,不要太依赖应用程序中的实际端点或它尝试下载的文件。您希望测试尽可能快地运行。

使用Jasmine你可以做一些事情:

使用间谍:

spyOn是一个函数,它可以存根给定的函数并跟踪传递给它的参数类型,可以看到其他函数调用它,甚至在它执行的代码执行时返回一个特定的值。

您可以使用间谍来查看$ .get请求是否会发生,然后您可以说返回一个特定值,然后继续测试该程序。

使用Jasmine Ajax插件

这是我喜欢在我的测试中使用的。 Jasmine有一个非常好的插件ajax.js。它简化了对任何ajax功能的测试。我喜欢做的是模拟实际的请求,所以当你的代码试图获得文件/响应时,代码将忽略实际的调用并模拟它,返回你可以指定的伪数据。

在开始之前,我也想在一个单独的函数中使用我的ajax方法,它只会返回一个promise。它更容易阅读/测试/维护,例如你可以像下面那样重写它:

this.loadNotificationCall = function(searchOption, searchKey) {
    var url = '@URLs.API.Notifications.Past' + '?searchOption=' + searchOption + '&searchValue=' + searchKey;
    return $.getJSON(url)
} 

this.loadNotification() {
    return this.loadNotificationCall()
        .done(function (nData) {
            //some code here
        })
        .fail(function (jqXHR, status, error) {
            showError('There was an error while fetching the records. Please try after some time. (' + jqXHR.status + ':' + jqXHR.statusText + ')');
        });
}

如果您使用虚拟数据加载测试应用程序,我猜您希望ajax请求文件具有特定路径。

您正在查看可以从

输出的最基本的默认版本
'@URLs.API.Notifications.Past' + '?searchOption=' + searchOption + '&searchValue=' + searchKey;

让我们说它就像

//'someapi?searchOption=1&searchValue=abc'

该网址需要与您的应用尝试联系的内容完全匹配。检查你的调试/ fiddler,看看是什么,以防万一。如果它不匹配(包括它试图发送的数据),模拟将失败,测试将超时。该错误通常类似于Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

一旦你做对了,你可以在下面的例子中模拟这个网址:

describe('when user gets the data', function() {

var sut = null;
var testCall = null;
var dummyData = {
    name: 'Jon Snow'
};
beforeEach(function() {
    jasmine.Ajax.install();
    jasmine.Ajax.stubRequest("someapi?searchOption=1&searchValue=abc").andReturn({
            responseText: JSON.stringify(dummyData)
    });

    sut = new yourApplication();
    testCall = sut.loadNotification();
});

afterEach(function() {
    jasmine.Ajax.uninstall();
});

// actual tests here

});

我也很确定你可以在这些模拟网址中使用通配符,所以这也应该是有效的:jasmine.Ajax.stubRequest("someapi?(.*)").andReturn(//

所以现在发生的事情是,如果你测试的东西会用$ .get来调用你的方法,那么请求就不会发生在你的服务器上,而是会被模拟,我们的虚拟数据将被返回。在这个例子中,它是一个带有name: 'Jon Snow'

的简单对象

现在,您希望测试看起来像这样:

it('should populate name', function(done) {
    testCall
        .done(function() {
            expect(sut.name).toEqual('Jon Snow');
            done();
        });
});

您将完成的参数传递给测试,以便在调用完成之前它不会完成。如果您在浏览器中调试它,您将看到文件中的代码将进入done方法并继续工作,因为它是一个真实的请求。 done(nData)中的数据将成为name: Jon Snow的虚拟对象。

如果您想测试失败的代码,可以向ajax插件添加一些其他设置:

jasmine.Ajax.stubRequest("someapi?searchOption=1&searchValue=abc").andReturn({
    status: 500,
    responseText: "{}"
});

我希望我没有这么多,我知道有简单的方法(例如只是在'ajax'上做$ .spy并看到最近的电话等但我喜欢我的方法,已经工作了非常好,我可以测试多个电话,链接电话,以及更多很酷的场景。