Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/396.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.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 JS:在对象实例化之前替换函数定义_Javascript_Backbone.js_Requirejs_Jasmine - Fatal编程技术网

Javascript JS:在对象实例化之前替换函数定义

Javascript JS:在对象实例化之前替换函数定义,javascript,backbone.js,requirejs,jasmine,Javascript,Backbone.js,Requirejs,Jasmine,我的require.js模块中有外部视图和内部视图。它们可以用几句话来描述: InnerViews在OuterViewrendering上实例化 InnerView调用自己实例化的computed方法 InnerView.calculate方法使用AJAX,这在单元测试中是不受欢迎的(使用jasmine) 我需要:在我的jasmine测试中替换innerView。使用直接调用innerView计算方法调用。HandlerResults使用硬编码数据参数 问题:问题还在于,在测试中,我只能访问

我的require.js模块中有
外部视图
内部视图
。它们可以用几句话来描述:

  • InnerView
    s在
    OuterView
    rendering上实例化
  • InnerView
    调用自己实例化的
    computed
    方法
  • InnerView.calculate
    方法使用AJAX,这在单元测试中是不受欢迎的(使用jasmine)
我需要:在我的jasmine测试中替换
innerView。使用直接调用
innerView计算
方法调用。HandlerResults
使用硬编码
数据
参数

问题:问题还在于,在测试中,我只能访问
outerView
。因此,我需要替换
innerView。在实例化
innerView
之前,计算
方法定义

问题:如何替换
innerView。在实例化
innerView
之前计算的
方法定义

代码:

    define(".....", function(...) {
      var innerView = Backbone.View.extend ({
        initialize: function() {
          ......
          calculate(opitons);
        },

        //I NEED TO REPLACE THIS WITH handleResults(hardcodedData)
        calculate: function(options) { 
          var $this = this;
          Utils.doSmth(options).then(
              $this.handleResults
          );
        },

        handleResults: function(data) {
          ....
        }
      });

      var outerView = Backbone.View.extend ({
        subViews: [],

        render: function() {
          subViews[0] = new innerView();
        }    
      });

      return outerView;
}

请记住,BDD的理念是测试行为。问问你自己,你真的想改变你的函数在单元测试中的工作方式吗?通过提供一个替代的代码路径,您并不是在测试将在生产中看到的实际行为

例如,如果在
then
函数中执行比简单调用
handleResults(…)
更复杂的数据处理,该怎么办?然后,您需要将此逻辑的知识引入单元测试,以便正确模拟链的其余部分

在我看来,您真正需要的是一种模拟AJAX请求的方法,而不是一种改变代码工作方式的方法。有几种方法可以实现这一点。其中两个最受欢迎的是:

  • ——茉莉花特有
  • --用于创建间谍、模拟和模拟HTTP服务器的独立框架

我曾多次使用Sinon.JS测试与XHR相关的代码路径,效果非常好。

对我来说,这似乎是一个设计问题。您在outerView中对innerView类型有一个硬编码的依赖项,并且将其隐藏在闭包(也称为模块)中。更糟糕的是,这种内部的、硬编码的依赖关系连接到了宇宙的其他部分(AJAX调用)。为了使其可测试,您必须以某种方式公开内部视图

在我看来,至少,你必须像这样打开你的外部视野:

var outerView = Backbone.View.extend ({
    subViews: [],

    initialize: function (options) {
        this.innerView = innerView;
    }

    render: function() {
      subViews[0] = new this.innerView();
    }    
  });
这样,在调用render之前,您至少可以在测试中修改outerview.innerView


在这一点上,实际上在
初始化
中注入依赖项只是一个小小的额外步骤,如果您觉得有必要,可以使用默认值(
this.innerView=options&&options.innerView | | innerView;
)?类似于:calculate:function(options){if(somevar){innerView.handleResults();}else{//do other..}}@StevoPerisic在测试中为应用程序代码引入标志是个坏主意。也许还有其他的方法?也许把jasmine测试代码显示为well@StevoPerisic那里没有什么特别的事情发生。在调用
outerView.render()
Ok之前,我只需要“模拟”该方法,在outerView渲染方法中实例化新的innerView之前,innerView应该作为对象可用,您可以做的是在调用render之前将calculate方法更改为指向HandlerResults方法<代码>innerView.calculate=innerView.HandlerResults然后调用RenderTanks!我们使用Sinon.JS,但我不知道如何再次用Itan替换mthod定义,因为我知道我需要在测试中引用
innerView
obj才能发现it方法,对吗?那么你能提供一个例子吗?