Javascript JS:在对象实例化之前替换函数定义
我的require.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使用硬编码数据参数 问题:问题还在于,在测试中,我只能访问
外部视图
和内部视图
。它们可以用几句话来描述:
s在InnerView
rendering上实例化OuterView
调用自己实例化的InnerView
方法computed
方法使用AJAX,这在单元测试中是不受欢迎的(使用jasmine)InnerView.calculate
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方法,对吗?那么你能提供一个例子吗?