【问题标题】:I'm new to TDD backbone with jasmine-sinon. change event in backbone unit test我是 jasmine-sinon 的 TDD 骨干新手。主干单元测试中的更改事件
【发布时间】:2012-09-07 06:29:39
【问题描述】:

我正在测试主干中选择框视图的事件更改,该视图“应该在更改时提供到 router.navigate 的正确路径”。这是场景,如果我在下拉列表中选择一个值,它应该重定向到正确的 url。

这是测试(campaign.test.js):

it('should provide the correct path to router.navigate when changed', function() {
    var routeName = 'test_campaign';
    var routerSpy = sinon.spy(Insights.router, 'navigate');

    this.view.$el.bind('change', function() {
      expect(routerSpy).toHaveBeenCalledWith('campaign/' + routeName, true);
    });

    //create the option element holding the test value
    this.view.$el.append($('<option value="' + routeName +'" selected="selected" />'));

    this.view.$el.trigger('change');


    routerSpy.restore();
  });

这是模块(campaign.js):

DropdownView: Backbone.View.extend({
  tagName: 'select',
  className: 'campaign-list',
  events: {
     'change' : 'navCampaign'
  },


  initialize: function() {
    _.bindAll(this);
    this.collection.on('reset', this.render);
    this.collection.on('add', this.addCampaign);

    //if no campaigns exist then add a dummy placeholder
    if(this.collection.models.length === 0) {
      this.$el.append('<option value="">No Campaigns</option>');
    }

  },


  navCampaign: function() {

    Insights.router.navigate();
  },


  addCampaign: function(campaign) {
    //remove the No Campaigns placeholder when campaigns are added
    var firstChild = this.$el.children(':first');
    if(firstChild.attr('value') === '') {
      firstChild.remove();
    }

    var view = new Insights.Campaign.DropdownItem({ model: campaign });
    var item = view.render().el;
    this.$el.append(item);
  },

  render: function() {
    this.collection.each(this.addCampaign);
    return this;
  }
})

在我的测试中,我创建了一个新的 OPTION 元素,然后设置了一个选中属性的值。

如何将其作为更改事件的 currentTarget 传递并发送到 trigger()?

或者有更简单的方法吗?

我的测试失败了。错误:使用“campaign/test_campaign”调用预期的函数,true。

【问题讨论】:

    标签: backbone.js tdd jasmine js-test-driver


    【解决方案1】:

    您的测试必须如下所示:

      it('should provide the correct path to router.navigate when changed', function() {
        var routeName = 'test_campaign';
        var routerSpy = sinon.spy(Insights.router, 'navigate');
        var view = new DropdownView();
    
        //create the option element holding the test value
        this.view.$el.append($('<option value="' + routeName +'" selected="selected" />'));
    
        this.view.$el.trigger('change');
        expect(routerSpy).toHaveBeenCalledWith('campaign/' + routeName, true);
    
        routerSpy.restore();
      });
    

    首先,您必须在测试中创建视图的实例,并且必须在创建视图之前创建间谍。两者都可以在beforeEach 块中完成。

    当您在事件处理程序中添加期望代码时,可能会在调用路由器上的导航方法之前调用它。因为两个处理程序被添加到侦听器中,一个用于在路由器上调用导航,另一个用于测试它是否在路由器上被调用。由于您无法确保首先调用哪个,因此当首先调用测试中的侦听器时,测试将失败。

    也许最好通过将带有数据的集合传递给视图来测试它,而不是直接在测试中设置视图元素的 DOM。因此,您还将测试您的 initializeaddData 方法是否有效。

    【讨论】:

    • 您好 Andreas 感谢您的帮助,我通过了测试。请参阅下面的答案。 :)
    【解决方案2】:

    以下是使此测试通过的更改。 :)

    我更改了变量 routeName 的值,在campaign.test.js

    来自

     var routeName = 'test_campaign';
    

     var routeName = this.view.$el.val();
    

    然后将此测试实施到 campaign.js

    navCampaign: function() {
        var newRoute = 'campaign/' + this.$el.val();
        Insights.router.navigate(newRoute, true);
      }
    

    我得到了这个绿色。 :)

    【讨论】:

      【解决方案3】:

      对不起,我想在队友的帮助下把这件事说清楚。

      var routeName = this.view.$el.val(); 指向空

      通过使值动态化,它会降低测试的有效性,

      所以我回var routeName = 'test_campaign'.

      这个测试的重点是根据一组预定义的输入来指定它所期望的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-25
        • 2012-08-10
        • 2012-08-10
        • 2012-09-26
        • 2011-12-11
        • 1970-01-01
        • 2012-01-16
        • 1970-01-01
        相关资源
        最近更新 更多