在测试 AJAX 请求(以及类似的,获取 json 文件等)时,检查您的代码是否可以处理完成和失败总是一个好主意。您还应该模拟您测试的数据,不要过多依赖应用程序中的实际端点或它尝试下载的文件。您希望测试尽可能快地运行。
使用 Jasmine 你可以做一些事情:
使用间谍:
spyOn 是一个函数,它可以存根给定函数并跟踪传递给它的参数类型,可以查看调用它的其他函数,甚至在它被监视的代码执行时返回特定值。
您可以使用 spy 来查看 $.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'
该 url 需要与您的应用程序将尝试联系的内容完全匹配。检查你的调试器/提琴手,看看是什么以防万一。如果不匹配(包括它尝试发送的数据),模拟将失败,并且测试将超时。错误通常看起来像Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
一旦你做对了,你就可以在下面的例子中模拟那个 url:
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 方法并继续工作,因为它是一个真实的请求。 done(nData) 中的数据将成为我们的虚拟对象name: Jon Snow。
如果你想测试一个失败的代码,你可以给 ajax 插件添加一些额外的设置:
jasmine.Ajax.stubRequest("someapi?searchOption=1&searchValue=abc").andReturn({
status: 500,
responseText: "{}"
});
我希望我没有让你感到厌烦,我知道有更简单的方法(比如只是在 'ajax' 上执行 $.spy 并查看最近的调用等,但我喜欢我的方法,已经奏效了非常好,我可以测试多个调用、链接调用以及更多很酷的场景。