Это работает, когда я запускаю пользовательский интерфейс в браузере, но я всегда получаю значение null для «d» в моем методе validateAsync, который должен вызывать метод done, чтобы вернуть его в метод сохранения. Я не могу понять, как использовать andCallFake (требуется для проверки уникального имени), но также заставить его возвращать (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...');
});
.done()
, где оно ожидает функцию. - person Beetroot-Beetroot   schedule 09.04.2013validateAsync()
иsave()
находится на стороне потребителя - изменения состояния управляются внутри методаuiDataService.GetIsLayoutNameUniqueAsync()
. Я не собираюсь пытаться комментировать Jasmine, кроме как сказать, что кажется совершенно бессмысленным писать и отлаживать код для отладки другого кода того же порядка сложности или проще. - person Beetroot-Beetroot   schedule 09.04.2013