这是我的javascript课
var CommunicationInterface = inherit(Interface, {
__constructor: function() {
this.heartBeatDuration = 60 * 1000;
this.client = null;
this._isSetupped = false;
this.__base();
},
setup: function() {
// console.log('xmpp interface setup started');
var _this = this;
var deferred = Q.defer();
if (this._isSetupped) {
deferred.resolve();
return deferred.promise;
}
CommConfig.get('params')
.then(function(params) {
_this.client = new Client({
id: params.id + '@' + config('HOST'),
password: params.password,
host: config('HOST'),
port: config('PORT'),
reconnect: true
});
_this.client.on('online', _this.onOnline.bind(_this));
setInterval(function() {
_this.heartBeat.bind(_this)(params.id);
}, _this.heartBeatDuration);
_this._isSetupped = true;
deferred.resolve();
}, function(err){
console.log(err);
});
return deferred.promise;
},
heartBeat: function(Id) {
var stanza = this._makeMessage({
'to': id + '@' + config('HOST'),
'type': 'chat'
}, '{}');
console.log('foo');
this.client.send(stanza);
console.log('bar');
},
onOnline: function() {
console.log('online');
this.client.send('online');
this.emitter.emit('online');
},
});
测试代码是:
describe('CommunicationInterface', function() {
var commInterface;
var stubGetConfig, stubCommClient, stubCommClientConnect, spyCommClientSend;
var clock;
before(function () {
var deferred = Q.defer();
stubGetConfig = sinon.stub(CommConfig, 'get')
.withArgs('params')
.returns(deferred.promise);
deferred.resolve({
'id': 'test',
'password': '123456',
});
stubCommClientConnect = sinon.stub(CommunicationInterface.Client.prototype,
'connect');
clock = sinon.useFakeTimers();
});
beforeEach(function () {
commInterface = new CommunicationInterface();
stubCommClient = sinon.spy(commInterface.client);
});
afterEach(function () {
stubCommClientConnect.reset();
stubGetConfig.reset();
stubCommClient.reset();
clock.restore();
});
it('test 1', function(done) {
commInterface.setup()
.done(function () {
var spyCommClientSend = sinon.spy(commInterface.client, 'send');
commInterface.client.emit('online');
assert.isTrue(spyCommClientSend.calledOnce);
assert.isTrue(spyCommClientSend.calledWithExactly('online'));
done();
});
});
it('test 2', function(done) {
var spyHeartBeat = sinon.spy(commInterface.__proto__, 'heartBeat');
commInterface.setup().done(function() {
var spyCommClientSend = sinon.spy(commInterface.client, 'send');
clock.tick(commInterface.heartBeatDuration + 10);
assert.isTrue(spyHeartBeat.calledOnce);
assert.isTrue(spyCommClientSend.called);
spyHeartBeat.restore();
done();
});
});
});
test 1
中的代码可以正常工作,并且spyCommClientSend
已正确创建,但是test 2
中的第二个断言失败,并且spyCommClientSend
不会监视实际对象。这可能是什么原因?
我确定正在调用
send
函数,因为打印了它周围的两个console.log
语句。 最佳答案
乍一看,我认为问题在于您的间谍正在查看commInterface.__proto__.heartBeat
,这意味着您断言在heartBeat
原型上调用CommunicationInterface
方法。这不会发生,因为当您进行sinon的时钟滴答时,heartBeat
调用位于您在commInterface
内部创建的beforeEach
实例上。
可以通过实际监视实例上的heartBeat
而不是原型来解决此问题,如下所示:var spyHeartBeat = sinon.spy(commInterface, 'heartBeat');
此外,我建议您通过将commInterface
调用中的afterEach
设置为undefined
或null
来清理它–只是为了确保每次测试都拥有一个全新的,完全干净的CommunicationInterface
实例案件。
希望这可以帮助!