gpt4 book ai didi

javascript - 对不受事件发射器绑定(bind)的事件进行单元测试

转载 作者:行者123 更新时间:2023-11-28 15:09:10 24 4
gpt4 key购买 nike

我有以下代码。

  private client: any;

this.client = mqtt.connect(url, mqttOptions);

this.client.on('message', (topic: string, message: string) => {
console.log('came inside onMessage');
let ksiotMessage: KSIOTMessage;
let receivedTopic: KSIOTTopic;
receivedTopic = getValue(topic);
ksiotMessage = {
ksiotTopic: receivedTopic,
payload: message
};
messageReceivedCallBack.onMessageReceived(ksiotMessage);
});

这里有一个匿名函数,当 mqtt 客户端发出消息事件时,该函数会被触发。我无法控制它,这意味着不是我将其绑定(bind)到事件发射器。另外,我无法添加计时器并等待此事件触发,因为我已经使用 sinon 模拟了客户端的连接。所以没有真正的联系。那么我如何手动发出此消息事件并查看是否调用了 messageReceivedCallBack 的 onMessageReceived ?我是 Javascript 单元测试的新手。目前我正在使用 mocha 和 sinon 来满足我的单元测试要求。

请指教。

最佳答案

首先有一个重要的免责声明:我不了解 TypeScript,也不了解您的应用程序的内部结构,因此以下内容可能无法开箱即用。但是,它可能会为您提供一些有关如何实现此类测试的想法。

我抽象了您的客户端代码(需要测试的代码):

// mqtt-module.js
const mqtt = require('mqtt');
const messageReceivedCallBack = require('./callbacks');

// This mimics what your code does. Instead of a class I just make it a
// simple function.
module.exports = {
setup() {
let client = mqtt.connect();
client.on('message', (topic, message) => {
// We want to test this.
messageReceivedCallBack.onMessageReceived(message);
});
}
}

在您的代码中,不清楚 messageReceivedCallBack 来自何处。因为您必须能够从 Sinon 访问它,所以它应该位于可导入模块中(但是,这确实依赖于导入被缓存的事实,就像使用 require() 一样,其中我'我不确定 TS 是否这样做)。

这是我使用的一个简单的模拟:

// callbacks.js
module.exports = {
onMessageReceived(message) {}
};

最后是测试本身。它相当复杂,因为它需要做各种事情:

  • 创建一个EventEmitter子类,用于替换原来的MqttClient
  • stub 各种函数和回调
  • 设置测试环境

代码:

// test.js
const mqtt = require('mqtt');

// The modules mentioned above.
const mqttModule = require('./mqtt-module');
const messageReceivedCallBack = require('./callbacks');

// Set up Sinon and Chai
const sinon = require('sinon');
const chai = require('chai');
let expect = chai.expect;
chai.use(require('sinon-chai'));

// Create a fake client for testing purposes.
const EventEmitter = require('events').EventEmitter;
class Client extends EventEmitter {}

// The test case.
describe('my test case', () => {
var mockClient;

beforeEach(() => {
mockClient = new Client();
// mqtt.connect() returns a fake client instance, with
// just enough logic to allow events to be emitted and
// received.
sinon.stub(mqtt, 'connect').returns(mockClient);

// Call the setup of our MQTT class (this will likely be
// entirely different in your case, but the idea is that
// it gets called _after_ `mqtt.connect()` gets stubbed.
mqttModule.setup();
});

afterEach(() => {
// Restore the original.
mqtt.connect.restore();
});

it('should call messageReceivedCallBack.onMessageReceived', () => {
// The message that we're going to pass.
let message = 'this is a test message';

// We want to stub messageReceivedCallBack.onMessageReceived()
sinon.stub(messageReceivedCallBack, 'onMessageReceived');

// Emit a `message` event on our mock client, which will trigger
// the `client.on('message', ...)` in your MQTT class.
mockClient.emit('message', 'topic', message);

// Test if the stub was called with the proper argument.
expect(messageReceivedCallBack.onMessageReceived).to.be.calledWith(message);

// Restore to the original function.
messageReceivedCallBack.onMessageReceived.restore();
});

});

关于javascript - 对不受事件发射器绑定(bind)的事件进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37403657/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com