![](/img/trans.png)
[英]Jasmine: Testing a function, being called from a different function using jasmine
[英]Testing a function that is called from an jQuery AJAX callback with Jasmine
我有一个对服务进行AJAX调用的函数。 我试图期望在发生故障时调用displayError函数。
我有接受URL的函数ajaxCall。 成功后,我将结果传递给displaySuccess,当发生错误时,我将细节传递给displayError。
function ajaxCall(url) {
$.ajax({
method: "GET",
url: url,
data: "json",
beforeSend: function (xhr) {
//Do Stuff
},
error: function(xhr, textStatus, errorThrown) { displayError(xhr, textStatus, errorThrow, url)},
success: function (results) { displaySuccess(result) }
});
}
function displayError(xhr, textStatus, errorThrow, url) {
//Do Stuff//
}
function displaySuccess(results) {
//Do Stuff//
}
在Jasmine中,我可以成功验证URL。 我的问题是在测试中以确保调用displayError和displaySuccess函数。
到目前为止,我对这个特定问题有以下几点。
describe('The ajaxCall component', function() {
it('should call the error function when the ajax call fails', function () {
var obj = {};
spyOn(obj, 'displayError');
spyOn($, "ajax").and.callFake(function (options) {
options.error();
});
ajaxCall('/myResource/get');
expect(obj.method).toHaveBeenCalled();
});
}
我对单元测试还有些陌生,因此我一直在寻找试图帮助他们的建议,但这些建议会使单元测试失败。 我在哪里错呢?
这一切都归结为您如何监视对象并编写可测试性更高的代码。 让我们研究一些策略。
如果您当前的代码不在对象内,则可以通过直接测试它们的实现来测试这些函数是否被调用。
您无需直接测试函数的调用,而可以直接测试其实现。
例
describe("strategy 1", function () {
var ajaxSpy;
beforeEach(function () {
ajaxSpy = spyOn($, 'ajax');
ajaxCall();
});
describe("error callback", function () {
beforeEach(function() {
spyOn(window, 'alert');
var settings = ajaxSpy.calls.mostRecent().args[0];
settings.error();
});
describe("when there is an error", function() {
it("should alert an error message", function() {
expect(window.alert).toHaveBeenCalledWith('Error');
});
});
});
});
尽管上述方法可行,但编写测试可能很麻烦。 理想情况下,您要分别测试调用和实现。
为此,我们可以监视这些功能。 由于它们位于全局名称空间中,因此您可以通过window
对象监视它们。
例
describe("strategy 2", function () {
var ajaxSpy;
beforeEach(function () {
ajaxSpy = spyOn($, 'ajax');
ajaxCall();
});
describe("error callback", function () {
beforeEach(function() {
spyOn(window, 'displayError');
var settings = ajaxSpy.calls.mostRecent().args[0];
settings.error();
});
describe("when there is an error", function() {
it("should alert an error message", function() {
expect(window.displayError).toHaveBeenCalled();
});
});
});
});
最终策略以及我建议的策略与第二种策略具有相似的设置,只是将实现封装到一个自定义对象中。
这样做可以通过在对象中包装功能来使代码更易于测试,并且避免使用全局命名空间(即window
)。
例
describe("solution 3", function() {
var ajaxSpy;
beforeEach(function() {
ajaxSpy = spyOn($, 'ajax');
ajaxService.ajaxCall();
});
describe("error callback", function() {
beforeEach(function() {
spyOn(ajaxService, 'displayError');
var settings = ajaxSpy.calls.mostRecent().args[0];
settings.error();
});
it("should alert an error message", function() {
expect(ajaxService.displayError).toHaveBeenCalled();
});
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.