【问题标题】:How to clear the DOM with multiple tests in single ember integration test file如何在单个 ember 集成测试文件中使用多个测试清除 DOM
【发布时间】:2015-07-24 12:17:21
【问题描述】:

我在 date-dropdown-test.js 中有两个测试:

moduleForComponent('forms/date-dropdown', 'Integration | Component | forms/date dropdown', {
  integration: true
});

test('it renders in month mode', function(assert) {
  assert.expect(2);

  // Set any properties with this.set('myProperty', 'value');
  // Handle any actions with this.on('myAction', function(val) { ... });

  this.render(hbs`{{forms/date-dropdown dateFormat='MMMM YYYY' daySpecific=false dayToUse=26 dateUnitsLong=24 startIncrement=1}}`);

  // Check 24 months appear
  assert.equal(this.$('option').length, 24);

  // Check next month is selected by default
  var today = new Date();
  today.setDate(1);
  today.setMonth(today.getMonth() + 1);
  today.setDate(26);
  var expected = moment(today).format('DD-MM-YYYY');

  assert.equal(this.$('select').val(), expected);

});

test('it renders in day mode', function(assert) {
  assert.expect(1);

  // Set any properties with this.set('myProperty', 'value');
  // Handle any actions with this.on('myAction', function(val) { ... });

  this.render(hbs`{{forms/date-dropdown dateFormat='MMMM YYYY' daySpecific=true dateUnitsLong=300 startIncrement=3}}`);

  // Check 300 days appear
  assert.equal(this.$('option').length, 300);

});

我遇到的问题是,当第二个测试运行第一个测试中的组件时,它仍然在 DOM 中,并由 this.$('option').length 找到。在 Ember 测试中或测试结束时清除 DOM 的正确方法是什么?

或者有什么比 this.$() 更具体的东西可以在测试中渲染的组件的上下文中使用?

编辑

让我更困惑的是,它似乎在 https://github.com/yapplabs/ember-radio-button/blob/master/tests/unit/components/radio-button-test.js 上通过多次测试和查看 dom 工作正常,但在我的第二次测试中,我肯定在 .length 中看到 324 个选项元素,而不是添加的 300 个由那个特定的组件。

编辑 2

组件代码为:

export default Ember.Component.extend({
  dateItems: [],
  didInitAttrs: function() {
    var today = new Date();
    var dateItems = this.get('dateItems');
    var i = 0;

    if (this.get('daySpecific')) {
      for (i = 0; i < this.get('dateUnitsLong'); i++) {
        var nextDay = new Date();
        nextDay.setDate(today.getDate() + i);
        dateItems.addObject({date: nextDay, value: moment(nextDay).format('DD-MM-YYYY')});
      }
    }
    else {
      for (i = 0; i < this.get('dateUnitsLong'); i++) {
        var nextMonth = new Date();
        nextMonth.setDate(1);
        nextMonth.setMonth(today.getMonth() + i);
        nextMonth.setDate(this.get('dayToUse'));
        dateItems.addObject({date: nextMonth, value: moment(nextMonth).format('DD-MM-YYYY')});
      }
    }

  },
  didInsertElement: function() {
    var startDate = new Date();
    if (this.get('daySpecific')) {
      startDate.setDate(startDate.getDate() + this.get('startIncrement'));
    }
    else {
      startDate.setDate(1);
      startDate.setMonth(startDate.getMonth() + this.get('startIncrement'));
      startDate.setDate(this.get('dayToUse'));
    }

    this.$('select').val(moment(startDate).format('DD-MM-YYYY')).trigger('change');
  },
  actions: {
    dateChange: function() {
      this.set('value', this.$('select').val());
    }
  }
});

hbs

<select class="form-control" {{action 'dateChange' on='change'}}>
  {{#each dateItems as |dateItem index|}}
      <option value="{{dateItem.value}}">
          {{date-formatter dateItem.date dateFormat}}
      </option>
  {{/each}}
</select>

这个想法是创建一个可重用的组件,该组件在给定的时间段内创建几个月或几天的下拉列表,并允许默认值不是第一天/第一个月。所以看看上面的第一个测试{{forms/date-dropdown dateFormat='MMMM YYYY' daySpecific=false dayToUse=26 dateUnitsLong=24 startIncrement=1}}会创建一个下拉列表,从这个月开始有 24 个月,默认到下个月。

无论如何,我想知道didInsertElement 的最后一行:this.$('select').val(moment(startDate).format('DD-MM-YYYY')).trigger('change'); 是否是这里的冒犯者?也许测试会继续进行,但这会停止测试中的拆解?

如果我删除一个或另一个,这两个测试会单独通过。

编辑 3

删除 this.$('select').val(moment(startDate).format('DD-MM-YYYY')).trigger('change'); 没有帮助,也许是我使用 didInitAttrs 来创建模板的 #each 使用的 dateItems?

【问题讨论】:

    标签: ember.js ember-cli


    【解决方案1】:

    我尝试了一个非常简单的应用程序,集成测试似乎在这里工作。

    import { moduleForComponent, test } from 'ember-qunit';
    import hbs from 'htmlbars-inline-precompile';
    
    
    moduleForComponent('x-div', 'Integration | Component | x div', {
      integration: true
    });
    
    test('it renders', function(assert) {
      assert.expect(2);
    
      // Set any properties with this.set('myProperty', 'value');
      // Handle any actions with this.on('myAction', function(val) { ... });
    
      this.render(hbs`{{x-div}}`);
    
      assert.equal(this.$().text(), '', 'should be an empty string, got "'+this.$().text()+'"');
    
      // Template block usage:
      this.render(hbs`
        {{#x-div}}
          template block text
        {{/x-div}}
      `);
    
      console.log(this.$('.thediv').length);
      assert.equal(this.$().text().trim(), 'template block text');
    });
    
    test('it renders again', function(assert) {
      assert.expect(2);
    
      // Set any properties with this.set('myProperty', 'value');
      // Handle any actions with this.on('myAction', function(val) { ... });
    
      this.render(hbs`{{x-div}}`);
    
      assert.equal(this.$().text(), '');
    
      // Template block usage:
      this.render(hbs`
        {{#x-div}}
          template block text
        {{/x-div}}
      `);
    
      console.log(this.$('.thediv').length);
      assert.equal(this.$().text().trim(), 'template block text');
    });
    

    this.$('.thediv').length 在两个测试中都返回 1,拆解已正确完成。

    组件代码是否会导致测试失败?

    【讨论】:

    • this.subject() 在组件集成测试中不可访问
    • 您上面的帖子几乎证明了它一定是我编写组件的方式的一个特定问题,我已经编辑了问题以获得我的组件代码。我目前的想法可能是创建每个在 didInitAttrs 中使用的 dateItems 应该以更好的方式完成,这就是原因?
    【解决方案2】:

    我认为这可能是 didInitAttrs 的一个错误,因此在 Github (http://rwjblue.jsbin.com/docepa/edit?html,js,output) 上发布了一个问题。事实证明,问题出在我的一行代码中:

    dateItems: [],
    

    该数组正在组件的原型上共享。正如https://dockyard.com/blog/2014/04/17/ember-object-self-troll 解释的那样:

    “当你不传递任何属性来创建(props)时,对象的所有实例将共享同一个原型。这几乎是原型继承的要点。这意味着对一个对象的任何更改都会反映在其他人。这解释了第一个示例中的行为。"

    如果我将组件两次放在同一页面上,那么我也会在测试环境之外看到问题。

    所以我有两个选择来解决这个问题,将 dataItems 转换为计算属性或使用 Init。我像这样使用init:

    dateItems: null,
    init: function() {
      this._super.apply(this, arguments);
      this.dateItems = [];
    },
    

    dateItems 现在在组件实例之间保持很好的区别。

    【讨论】:

      猜你喜欢
      • 2020-03-18
      • 2016-01-19
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多