Großer Disclaimer zuerst: Ich kenne weder TypeScript, noch die Interna Ihrer Anwendung, daher funktioniert das Folgende möglicherweise nicht out-of-the-box. Es kann Ihnen jedoch einige Ideen geben, wie Sie diese Art von Tests implementieren können.
ich Ihren Client-Code abstrahiert (der Code, das ist muss getestet werden): von
// 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);
});
}
}
In Ihrem Code, es ist nicht klar, wo messageReceivedCallBack
kommt. Da Sie von Sinon darauf zugreifen können müssen, sollte es in einem importierbaren Modul sein (dies beruht jedoch auf der Tatsache, dass Importe zwischengespeichert werden, wie bei require()
, von denen ich nicht sicher bin, ob TS dies tut).
Hier ist ein einfaches Mock, die ich verwendet:
// callbacks.js
module.exports = {
onMessageReceived(message) {}
};
Schließlich ist der Test selbst. Es ist vielmehr zu erarbeiten, weil es verschiedene Dinge tun muss:
- erstellen
EventEmitter
Unterklasse, die die ursprünglichen MqttClient
mit
- Stub die verschiedenen Funktionen und Rückrufe verwendet wird
- die Testumgebung zu ersetzen bis
Der Code:
// 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();
});
});
Ihr Testcode Zugang zu muss 'this.client' und' messageReceivedCallBack'. Ist das der Fall? – robertklep
this.client ist ein Wert aus der Zeile "mqtt.connect" zugewiesen. Deshalb gebe ich meinen eigenen Stub zurück. Ich muss wissen, wie ich dieses Verbindungsereignis auslösen kann, damit ich den Code innen prüfen kann. Da ich die connect-Methode beendet habe, wird das Ereignis "message" nicht automatisch ausgelöst. Ich muss es manuell auslösen. Ich weiß nicht wie :( – mayooran