Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 测试从主干上的触发器点击。视图打开一个新的主干。视图_Javascript_Backbone.js_Jasmine_Marionette - Fatal编程技术网

Javascript 测试从主干上的触发器点击。视图打开一个新的主干。视图

Javascript 测试从主干上的触发器点击。视图打开一个新的主干。视图,javascript,backbone.js,jasmine,marionette,Javascript,Backbone.js,Jasmine,Marionette,我有两个主干视图,MainView和PopupView MainView包含一个帮助按钮。当启动帮助按钮处理程序时,它将显示Backbone.View 我的问题是如何从MainView模块测试这种行为 以下是我关于MainView的代码: var MainView = Backbone.View.extend({ events: { 'click #help' : 'showPopUp' }, showPopUp: function() {

我有两个主干视图,
MainView
PopupView

MainView包含一个帮助按钮。当启动帮助按钮处理程序时,它将显示Backbone.View

我的问题是如何从
MainView
模块测试这种行为


以下是我关于
MainView
的代码:

var MainView = Backbone.View.extend({
    events: {
        'click #help' : 'showPopUp'
    },

    showPopUp: function() {
       var popupView = new PopupView();
       app.vent.trigger('showModal', popupView);
    }    
});

以下是我关于mainView.spec的代码:

describe("When help button handler fired", function() {
    beforeEach(function() {
        this.view.render();
        this.view.$el.find('#help').trigger('click');
    });
    it("shows the popup", function() {
        // what should I do?
    });
});

以下是我的应用程序代码:

var app = new Marionette.Application();

app.addRegions({
    header: '#header',
    sidebar: '#sidebar',
    main: '#main',
    modal: '#modal'
});

app.vent.on('showModal', function(view) {
    var modal = app.modal;

    modal.show(view);
    modal.$el.modal({
        show: true,
        keyboard: true,
        backdrop: 'static'
    });
});

所以你的主视图不应该打开弹出窗口,它甚至不应该知道这样的东西存在。它应该通过事件总线通知其他模块,弹出窗口应该通过触发事件打开

当你使用app.vent时,我假设你使用的是木偶。在我的项目中,我有一个木偶区域来处理叠加视图。该区域应打开/关闭视图

这样做,更容易测试。在主视图中,您可以监视
app.vent
功能,并测试在单击按钮时是否将执行该功能。在您所在的地区,您可以在
app.vent
上触发事件,并监视您的
view.render
功能


在您想要测试的对象中创建新实例会使测试变得更加困难。当然,在JavaScript中更容易,例如在Java中,因为您可以在JavaScript中的运行时覆盖现有函数,但使用某种依赖项注入方式可以更容易地模拟和监视依赖项。

如果您使用的是Sinon和Chai,您可以尝试以下方法:

describe("When help button handler fired", function() {
  beforeEach(function() {
      this.popupSpy = sinon.spy()
      app.vent.on('showModal', this.popupSpy);
      this.view.render();
      this.view.$el.find('#help').trigger('click');
  });
  it("shows the popup", function() {
      this.popupSpy.callCount.should.equal(1);
      this.popupSpy.args[0][0].should.be.an.instanceOf(PopupView);
  });
});
这个怎么样:

describe("When help button handler fired", function() {
    var popupShown;

    beforeEach(function() {
        popupShown = false;

        this.view.render();
        app.vent.on('showModal', function() {
            popupShown = true;      
        });
        this.view.$el.find('#help').trigger('click');
    });
    it("shows the popup", function() {
        expect(popupShown).toBe(true);
    });
});
尽管如此,我还是要推荐几件事:

  • 正如其他地方提到的,不要在MainView中创建模态视图。这使两者结合得太紧密了
  • 在测试中,您可能想说类似于
    it(“触发帮助事件”)
    或类似的话。这一点尤其重要,因为您正在隔离地对该对象进行单元测试。对于集成测试,情况正好相反
  • 我不确定您在每个函数之前的
    中是否做得太多。您可能希望至少触发
    it
    范围内的按钮点击,尽管根据您所描述的内容,这可能是可以的

  • 谢谢你的回答。是的,你说得对,我正在使用
    木偶。我用代码更新了我的问题,关于应用程序的
    木偶.Region
    。尽管如此,我不清楚如何在我的规范中监视
    视图。渲染
    。有什么想法吗?谢谢。您可以将视图传递到区域的构造函数中,这样您就可以在测试中通过间谍。或者您可以监视视图的构造函数()并返回一个spy。谢谢您的回答
    this.popuppy.callCount.should.equal(1)
    有效;我不确定
    这个.popuppy.args[0].should.be.an.instanceOf(PopupView)。实际上,
    this.popuppy.args[0]。instanceof
    未定义。有什么想法吗?我得到以下错误
    Object[Object Object]没有方法'instanceOf'。无论如何
    this.popuppy.callCount.should.equal(1)`should
    expect(this.popuppy.callCount).toBe(1)
    this.popuppy.args[0][0].should.be.an.instanceOf(PopupView)
    应该是
    expect(this.popuppy.args[0][0]).instanceOf(this.view)
    我的语法适用于摩卡和柴,但你的语法似乎适合茉莉花。它们在功能上应该是等价的。