我有这样的功能:
function foo () {
obj.method(1);
obj.method(2);
obj.method(3);
}
Run Code Online (Sandbox Code Playgroud)
为了测试它,我想做3个测试(使用Mocha TDD和Sinon):
test('medthod is called with 1', function () {
var expectation = sinon.mock(obj).expects('method').once().withExactArgs(1);
foo();
expectation.verify();
});
test('medthod is called with 2', function () {
var expectation = sinon.mock(obj).expects('method').once().withExactArgs(2);
foo();
expectation.verify();
});
test('medthod is called with 3', function () {
var expectation = sinon.mock(obj).expects('method').once().withExactArgs(3);
foo();
expectation.verify();
});
Run Code Online (Sandbox Code Playgroud)
使用该系统,sinon在每次测试时都会出现"意外呼叫"消息.
我已经解决了它将树测试加入到一个:
test('medthod is called with 1, 2 and 3', function () {
var mock = sinon.mock(obj);
mock.expects('method').once().withExactArgs(1);
mock.expects('method').once().withExactArgs(2);
mock.expects('method').once().withExactArgs(3);
foo();
mock.verify();
});
Run Code Online (Sandbox Code Playgroud)
但我希望有三个测试,而不是三个断言/期望. …
我正在开发chrome的扩展程序,并且每次用户在Google中搜索时我都会尝试执行操作.目前我正在使用chrome.webRequest onBeforeRequest监听器.它完全适用于大多数情况,但有些请求是通过缓存完成的,并且不执行任何调用.我在有关缓存的API文档中发现了这一点:
Chrome使用两个缓存 - 磁盘缓存和非常快速的内存缓存.内存高速缓存的生命周期附加到呈现过程的生命周期,该过程大致对应于选项卡.从内存缓存中回答的请求对Web请求API是不可见的.如果请求处理程序更改其行为(例如,阻止请求的行为),则简单页面刷新可能不会考虑此更改的行为.要确保行为更改通过,请调用handlerBehaviorChanged()以刷新内存缓存.但是不要经常这样做; 刷新缓存是一项非常昂贵的操作.注册或取消注册事件侦听器后,无需调用handlerBehaviorChanged().
我尝试使用handlerBehaviorChanged()方法清空内存缓存,但没有区别.虽然我不建议我在每次请求后都试着打电话给它.
这是我的代码:
chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES = 1000;
chrome.webRequest.onBeforeRequest.addListener(function (details) {
//perform action
chrome.webRequest.handlerBehaviorChanged();
} {
urls: ["*://*.google.com/*"]
});
Run Code Online (Sandbox Code Playgroud)
有没有办法从扩展中清空/禁用此内存缓存?
我有一些创建单例的遗留代码:
define(['backbone', 'MyModel'], function (Backbone, MyModel) {
var MyCollection = Backbone.Collection.extend({
model: MyModel,
initialize: function () {
//...
}
});
return new MyCollection();
});
Run Code Online (Sandbox Code Playgroud)
出于测试目的,我需要生成新实例以将它们作为依赖项注入.
有没有办法在不修改原始代码的情况下生成单例的新实例?
我带来了一个解决方案:将类添加为instace的属性
initialize: function () {
this.ClassObject = MyCollection;
//...
}
Run Code Online (Sandbox Code Playgroud)
然后实例化它
var myCollection = require('myCollection');
var myCollectionInstance = new myCollection.ClassObject();
Run Code Online (Sandbox Code Playgroud)
这个解决方案修改了类,我想避免它.
我还尝试创建单例的副本:
function generateNewCollection() {
var F = function () {};
F.prototype = myCollection;
return new F();
}
Run Code Online (Sandbox Code Playgroud)
它生成一个新实例,但它不会创建其依赖项的新实例,因此下一次测试的环境仍然很脏.
如何从该类的实例生成该类的新实例?
考虑下一个类及其实例:
// Create a new class
var Foo = function Foo () {
console.log('New instance of FOO!');
};
Foo.prototype.generate = function(first_argument) {
this.arr = [1,2,3,4,5];
};
var foo = new Foo();
foo.generate();
console.log(foo.arr); // [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)
请注意,它foo是一个实例 fo Foo,我将在示例中使用该实例。
使用 Object.create 我可以生成 foo 实例的新副本,但它们将共享状态数据:
var bar = Object.create(foo);
console.log(bar.arr); // [1,2,3,4,5]
bar.arr.push(6);
console.log(foo.arr); // [1,2,3,4,5,6]
console.log(bar.arr); // [1,2,3,4,5,6]
Run Code Online (Sandbox Code Playgroud)
如果某些逻辑位于构造函数中,则不会调用它。
这与对象创建类似,但它调用构造函数。它仍然存在相同的状态数据问题:
var Bar = function () {
foo.constructor.call(this);
};
Bar.prototype = foo;
var bar …Run Code Online (Sandbox Code Playgroud) Q承诺的范围如何运作?据我所知,"then"的回调由window调用,就像setTimeout一样.
在这个例子中(只是一个例子来了解它是如何工作的):
var getFileText = function() {
var deferred = Q.defer();
Server.readFile("foo.txt", "utf-8", function (error, text) {
if (error) {
deferred.reject(new Error(error));
} else {
deferred.resolve(text);
}
});
return deferred.promise;
};
var Foo = function () {
getFileText().then(this.showFile);
};
Foo.prototype.showFile = function(text) {
this.text = text;
console.log(text);
};
var foo = new Foo();
Run Code Online (Sandbox Code Playgroud)
要在foo的实例中使用我正在使用bind的文本:
var Foo = function () {
getFileText().then(this.showFile.bind(this));
};
Run Code Online (Sandbox Code Playgroud)
还有其他方法吗?