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 может использоваться совместно для решения аналогичных случаев использования.

Другие вопросы по тегам