Ember-CLI 单元测试 - 控制器打开引导模式



正在尝试为我的余烬控制器编写单元测试。 它只是更改一个属性,然后打开一个引导模式。 很难弄清楚如何测试模态是否实际打开。 不确定这是否属于单元测试或集成测试。 如果它不在我的单元测试中,那么以后似乎很难确定代码覆盖率。 引导程序版本: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');
});

无断言错误

阿拉伯数字。

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();
}

有关如何测试此类内容的任何其他建议或最佳实践将不胜感激。

附言 还尝试在单击之前添加以下内容:

$.support.transition = false;

根据某人的建议,但它不会禁用模态转换。

我遇到了同样的问题。我不确定这是最好的解决方案,但我通过在调用 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 支持从测试返回 promise,因此在此版本中,不再需要调用 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';

您还必须在 /tests/.jshintrc"predef" 数组中添加"waitForModalOpen"以避免 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');
  ....
});

如本示例所示registerWaiterregisterAsyncHelper可以结合使用来解决类似的用例。

最新更新