Я изучаю Магистраль и хочу «высмеять» результаты вызова .fetch()
в рамках модели. Я не хочу использовать тестовую библиотеку или на самом деле удалять внешнюю службу.mock Ответ JSON в Backbone Fetch?
В основном у меня есть настройка в моей модели, где, если this.options.mock === true
, то просто используйте внутренний объект JSON в качестве «результата» извлечения. Кроме того, на самом деле он обращается к API с помощью реального запроса AJAX.
Однако это не работает. Мое представление успешно отображает данные модели, когда я попадаю в фактический API («реальная» выборка), но не каждый раз, когда я пытаюсь передать поддельные данные.
Есть ли способ подделать ответ Fetch в магистрали без привлечения библиотеки тестирования, такой как Sinon?
вот полная модель (по крайней мере, соответствующие ее части). В принципе, модель извлекает данные и форматирует их для шаблона. а затем вид, который владеет моделью, отображает его.
'use strict';
(function (app, $, Backbone) {
app.Models.contentModel = Backbone.Model.extend({
/**
* Initializes model. Fetches data from API.
* @param {Object} options Configuration settings.
*/
initialize: function (options) {
var that = this;
that.set({
'template': options.template,
'mock': options.mock || false
});
$.when(this.retrieveData()).then(function (data) {
that.formatDataForTemplate(data);
}, function() {
console.error('failed!');
});
},
retrieveData: function() {
var that = this, deferred = $.Deferred();
if (typeof fbs_settings !== 'undefined' && fbs_settings.preview === 'true') {
deferred.resolve(fbs_settings.data);
}
else if (that.get('mock')) {
console.info('in mock block');
var mock = {
'title': 'Test Title',
'description': 'test description',
'position': 1,
'byline': 'Author'
};
deferred.resolve(mock);
}
else {
// hit API like normal.
console.info('in ajax block');
that.fetch({
success: function (collection, response) {
deferred.resolve(response.promotedContent.contentPositions[0]);
},
error: function(collection, response) {
console.error('error: fetch failed for contentModel.');
deferred.resolve();
}
});
}
return deferred.promise();
},
/**
* Formats data on a per-template basis.
* @return {[type]} [description]
*/
formatDataForTemplate: function (data) {
if (this.get('template') === 'welcomead_default') {
this.set({
'title': data.title,
'description': data.description,
'byline': data.author
});
}
// trigger the data formatted event for the view to render.
this.trigger('dataFormatted');
}
});
})(window.app, window.jQuery, window.Backbone);
Соответствующий бит с точки зрения (ContentView):
this.model = new app.Models.contentModel({template: this.templateName});
this.listenTo(this.model, 'dataFormatted', this.render);
ли данные быть установлены так быстро, что слушатель не был установлен еще?
Не могли бы вы включить немного больше кода, окружающего ваш блок if-else? Где в модели это и как она называется? Запомните [mcve] (https://stackoverflow.com/help/mcve). Из кода, который вы опубликовали, для кого-то еще трудно определить, что случилось. – ivarni
'fetch()' запускает ряд зависимых событий, которые вы не можете получить таким способом. Вы должны переопределить [Backbone.sync] (http://backbonejs.org/#Sync) – hindmost
@ivarni Я добавил свою полную модель к исходному сообщению. – Prefix