当我在浏览器中运行用户界面时,这是行得通的,但我总是在我的validateAsync方法中需要调用done方法以使其恢复保存中的'd'方法。我无法弄清楚如何使用andCallFake(需要间谍独特的名称测试),但也让它返回(jQuery)延期调用完成。 希望这段代码能给你足够的上下文来看看我正在努力完成什么。使用Jasmine测试嵌套承诺
validateAsync = function() {
var d,
isValid = true,
isUnique = false;
// validate that name and description are given
if (layout.Name() === '') {
toastr.warning('Layout name is required', 'Layout');
isValid = false;
}
// validate that there are no other layouts of the same type with the same name
d = uiDataService.GetIsLayoutNameUniqueAsync(layout.LayoutId(), layout.Name(), layout.LayoutTypeId())
.done(function (isUniqueResult) {
isUnique = isUniqueResult.toLowerCase() === "true";
if (!isUnique) {
toastr.warning('Layout name ' + layout.Name() + ' must be unique. There is already a layout with this name.', 'Layout');
}
// this is always undefined in my Jasmine tests
d.done(isValid && isUnique);
})
.fail(function (response) {
mstar.AjaxService.CommonFailHandling(response.responseText);
});
return d;
},
save = function() {
validateAsync()
.done(function (isValidResult) {
var isValid = isValidResult.toLowerCase() === "true";
if (!isValid) {
return;
}
// show a toastr notification on fail or success
dataContext.SaveChanges(layout, uiDataService)
.done(function (layoutIdFromSave) {
toastr.success('The layout was saved. Refreshing...');
})
.fail(function() {
toastr.error('There was an error saving the layout.');
})
.always(function() {
// toastr.info('finished');
});
})
.fail(function() {
throw new Error('There was an error validating before save');
});
};
// in uiDataService
getIsLayoutNameUniqueAsync = function (layoutId, layoutName, layoutTypeId) {
return ajaxService.AjaxGetJsonAsync(webServiceUrl + "GetIsLayoutNameUnique?layoutId=" + layoutId + "&layoutName=" + escape(layoutName) + "&layoutTypeId=" + layoutTypeId);
},
// in ajaxService
ajaxGetJsonAsync = function (url, cache) {
return $.ajax({
type: "GET",
url: url,
dataType: "json",
accepts: {
json: "application/json"
},
cache: cache === undefined ? false : cache
});
},
// in a beforeEach
var getIsLayoutNameUniquePromiseSpy = spyOn(mstar.dataService.UiDataService, "GetIsLayoutNameUniqueAsync")
.andCallFake(function() {
spyObj.called = true;
// http://stackoverflow.com/questions/13148356/how-to-properly-unit-test-jquerys-ajax-promises-using-jasmine-and-or-sinon
var d = $.Deferred();
d.resolve('true');
return d.promise();
});
// and a test
it("should show a toastr", function() {
// Act
vm.GetLayout().Name('Test');
vm.GetLayout().Description('Test');
vm.Save();
// Assert
expect(toastr.success).toHaveBeenCalledWith('The layout was saved. Refreshing...');
});
您正在将一个布尔值传递给'.done()',它需要一个函数。 – 2013-04-08 20:22:19
@ Beetroot-Beetroot done()应该在保存方法中将.done烧掉。 $ .Deferred()有一个.resolve方法,但我不认为$ .Deferred()。promise()有一个.resolve方法。 – Aligned 2013-04-08 20:32:39
这是正确的,只有一个Deferred具有状态改变方法,而从Deferred派生的Promise是一个“消费者”对象(与Deferred本身一样)可以响应状态更改。但请不要挂在这一点上,因为'validateAsync()'和'save()'中的所有内容都在客户端 - 状态的改变在'uiDataService.GetIsLayoutNameUniqueAsync()'方法内部管理。我不打算试图对Jasmine发表评论,除了编写和调试代码来调试其他复杂或简单顺序的代码似乎完全没有意义。 – 2013-04-09 00:14:35