ember-cli unit test - контроллер открывает мод загрузки
Пытаюсь написать юнит-тест для моего контроллера ember. Он просто меняет свойство, а затем открывает модал начальной загрузки. Трудно понять, как проверить, что модал действительно открывается. Не уверен, что это даже относится к юнит-тестам или интеграционным тестам. Если его нет в моем модульном тесте, кажется, что будет сложно определить охват кода позже. Версия начальной загрузки: 3.3.1, версия ember-cli 0.1.5, узел 0.10.33. Вот что я пытался безрезультатно:
1.
test('loginClick() opens modal', function(){
var controller = this.subject();
$('#login-modal').on('show.bs.modal', function(){
equal(true, true, "the show.bs.modal event fired");
});
controller.send('loginClick', 'anything');
});
нет ошибки подтверждения
2.
test('loginClick() opens modal', function(){
var controller = this.subject();
andThen(function(){
controller.send('loginClick', 'anything');
stop();
Ember.run.later(function(){
start();
equal($('#login-modal').hasClass('in'), true, "has the 'in' class");
}, 500);
});
});
и тогда не определено
Вот контроллер:
loginClick: function(param){
this.set('provider', param);//facebook or google
$('#login-modal')
.modal();
}
Будем благодарны за любые другие предложения или рекомендации по тестированию такого рода вещей.
ps также попытался добавить это до щелчка:
$.support.transition = false;
по чьему-то предложению, но это не отключает модальный переход.
2 ответа
У меня такая же проблема. Я не уверен, что это лучшее решение, но я решил его, зарегистрировав помощника асинхронного теста перед вызовом App.injectTestHelpers():
Ember.Test.registerAsyncHelper 'waitForModalOpen', (app, modal) ->
# If using QUnit < 1.16, you need to add stop().
#stop()
Ember.Test.promise (resolve, reject) ->
modal.on 'shown.bs.modal', ->
resolve()
# If using QUnit < 1.16, you need to add start().
#start()
Затем я вызываю его после нажатия кнопки и перед утверждениями:
modal = find '#testModal'
click '#openModal'
waitForModalOpen modal
andThen ->
strictEqual modal.attr('aria-hidden'), 'false', 'modal should be visible'
strictEqual modal.hasClass('in'), true, 'modal should have .in class'
Вот тестовый пример JS Bin. QUnit 1.16 поддерживает возврат обещаний из тестов, поэтому в этой версии вызов stop() и start() больше не нужен: QUnit будет ожидать разрешения обещания andThen().
Изменить: использовать в Ember-Cli
В документации ember-cli есть раздел о написании собственных помощников по тестированию.
Создайте помощника как /tests/helpers/wait-for-modal-open.js
:
import Ember from "ember";
export default Ember.Test.registerAsyncHelper('waitForModalOpen', function(app, modal) {
return Ember.Test.promise(function(resolve, reject) {
return modal.on('shown.bs.modal', function() {
return resolve();
});
});
});
Затем добавьте эту строку в /tests/helpers/start-app.js
:
import waitForModalOpen from './wait-for-modal-open';
Вы также должны добавить "waitForModalOpen"
в "predef"
массив в /tests/.jshintrc
чтобы избежать ошибок JSHint.
Наконец, создайте тест в виде файла в /tests/integration
:
import Ember from "ember";
import { test } from 'ember-qunit';
import startApp from '../helpers/start-app';
var App;
module('Bootstrap Modal Open', {
setup: function() {
App = startApp();
return visit('/');
},
teardown: function() {
Ember.run(App, App.destroy);
}
});
test('clicking the button should open a modal', function() {
var modal;
modal = find('#testModal');
click('#openModal');
waitForModalOpen(modal);
return andThen(function() {
strictEqual(modal.attr('aria-hidden'), 'false', 'modal should be visible');
return strictEqual(modal.hasClass('in'), true, 'modal should have .in class');
});
});
Другое общее решение - создать асинхронный помощник. waitUntil
который ждет появления html.
Ember.Test.registerAsyncHelper('waitUntil', function(app, selector, callback) {
var waiter = function() {
return $(selector).length > 0;
};
Ember.Test.registerWaiter(waiter);
var promise = app.testHelpers.wait();
promise.then(function() {
Ember.Test.unregisterWaiter(waiter);
});
// it will be resolved when the pending events have been processed
// (routing loads, ajax requests, run loops and waiters)
return promise;
});
Затем, waitUntil
может использоваться с другими асинхронными помощниками как:
waitUntil('#my-button');
click('#my-button');
или перед любым помощником синхронизации как:
waitUntil('#my-modal.modal').then(function() {
var el = find('#my-modal.modal');
assert.ok(el.length > 0, 'modal was open');
....
});
Как показывает этот пример registerWaiter
а также registerAsyncHelper
может использоваться совместно для решения аналогичных случаев использования.