【问题标题】:Jasmine: Backbone.history.loadUrl Breaks Unrelated TestsJasmine:Backbone.history.loadUrl 打破了不相关的测试
【发布时间】:2013-09-28 15:10:48
【问题描述】:

我发现导航到不同 URL 以进行视图和路由器行为测试的唯一方法是使用 Backbone.history.loadUrl()。 Backbone.history.navigate('#something', true) 和 router.navigate('#something, {trigger: true, replace: true} 及其任何组合在测试中不起作用。我的应用程序不使用 pushstate。

这在单个测试的上下文中正常工作。

describe('that can navigate to something as expected', function(){
  beforeEach(function() {
    this.server = sinon.fakeServer.create();
    //helper method does my responds to fetches, etc. My router in my app is what starts Backbone.history
    this.router = initializeBackboneRouter(this.server, this.fixtures, false);
  }); 
  afterEach(function(){
    this.server.restore();
    Backbone.history.stop();
    Backbone.history.loadUrl('#');
  });

  it('should create the view object', function(){
    Backbone.history.loadUrl('#something');
    expect(this.router.myView).toBeDefined();
  });
});

在测试期间,您可以看到主干按照预期将哈希附加到 URL:localhost:8888/#something 取决于测试。

不幸的是,loadUrl 似乎在测试行为方式中引入了很多不一致的地方。在我的一项涉及一些异步 JS 的测试中,我需要等待 AJAX 调用完成,大约 50% 的时间失败,超时或有时需要定义未定义。如果我消除了我期望的数据,那么我知道这不是 BS 测试。

it('should add the rendered html to the body', function(){
  runs(function(){
    Backbone.history.loadUrl('#something');
  });
  waitsFor(function(){
    var testEl = $('#title');
    if(testEl.length > 0){ return true; }
  }, 1000, 'UI to be set up');
  runs(function(){
    var testEl = $('#title');
    expect(testEl.text()).toEqual(this.router.model.get(0).title);
  });

});

这里重要的一点是,它只有在所有测试都运行时才会失败;它自己运行,它通过 100% 的时间。

然后我的问题是:Backbone.history.loadUrl 是围绕 jasmine 中的主干应用程序进行编程导航的不好方法吗?我觉得我已经尝试了一切来模拟用户访问特定 URL。我的拆解不正确吗?我试过没有 Backbone.history.loadUrl('#');并获得了不同的行为,但没有通过测试。

核心问题似乎是在几个、数百个甚至几个 jasmine 测试的上下文中,Backbone.history 并没有清除自己,而是作为一个自身的实例存在,而不是在每次测试。

【问题讨论】:

    标签: backbone.js jasmine


    【解决方案1】:

    这太糟糕了。 解决方案是稍微编辑我的代码以添加一个加载完成标志,当我确定 DOM 已 100% 完成加载时,该标志设置为 true。

    然后我在每个测试的根目录中的 beforeEach 函数中编写了一个辅助函数,等待该标志为真。

    var waitForLoadingComplete = function(view){
      waitsFor(function(){
        if(view.loadingComplete == true){return true;}
      }, 100, 'UI Setup Finished');
    }
    

    之后我将我的设置重构为一个辅助函数:

    var setupViewTestEnvironment = function(options) {
      var temp = {};
      temp.server = sinon.fakeServer.create();
      temp.router = initializeBackboneRouter(temp.server, options.fixture);
      waitForLoadingComplete(temp.router.initialview);
      runs(function(){
        Backbone.history.loadUrl(options.url);
        temp.view = temp.router[options.view];
        temp.model = temp.router[options.model];    
        waitForLoadingComplete(temp.view);
      });
      return temp;
    }
    

    使用示例:

      beforeEach(function() {
        this.testEnv = setupViewTestEnvironment({
          url: '#profile', 
          view: 'profileIndex', 
          model: 'myModel', 
          fixture: this.fixtures
        });  
      }); 
    

    之后,我看到了我已经加载的视图,我可以确定它已经完成加载,这样我就可以在 DOM 上测试东西或我想做的任何其他事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      • 1970-01-01
      相关资源
      最近更新 更多