当我在浏览器中运行UI时,这是有效的,但是我的validateAsync方法中的'd'总是为null,需要调用done方法将其恢复为save方法。我无法弄清楚如何使用andCallFake(需要spyOn的唯一名称测试),还要让它返回(jQuery)延迟调用完成。 希望这段代码能为您提供足够的上下文来查看我想要完成的任务。
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...');
});
答案 0 :(得分:2)
对齐,我不太了解Jasmine,但是根据自己的优点获取代码,如果它被剥离了,那就更容易看到它们正在发生什么对于骨头。
非常简化,validateAsync()
目前的结构如下:
validateAsync = function () {
...
var d = fn_that_returns_a_promise().done(function() {
...
d.done(boolean);
}).fail(function() {
...
});
return d;
};
哪个不对,因为.done()
不接受布尔参数,而我不能说它肯定是错的,d.done()
在d.done()
处理程序中并不合适(尽管可能在不同情况下)。
我建议您使用.then()
来过滤成功案例(从而传递一个用您的布尔值解析的新承诺),同时保留.fail()
的失败案例;给出如下结构:
validateAsync = function () {
...
return uiDataService.GetIsLayoutNameUniqueAsync(...).then(function(...) {
...
return isValid && isUnique;
}).fail(function(...) {
...
});
};
因此,save()
可以如下:
save = function() {
validateAsync().done(function(isValid) {
//validation success
if(!isValid) return;
...
}.fail(function() {
//validation failure
...
});
};
现在你所要做的就是"加入点#34; (即重新插入自己的陈述等)并希望我没有犯任何错误。