2016-05-24 15 views
0

gebunden ist Ich habe den folgenden Code.Einheit, die ein Ereignis testet, das nicht durch Ereignisemitter

Hier befindet sich eine anonyme Funktion, die ausgelöst wird, wenn ein Nachrichtenereignis vom mqtt-Client ausgegeben wird. Ich habe keine Kontrolle darüber, was bedeutet, dass ich es nicht mit einem Ereignissender verbunden habe. Ich kann auch keinen Timer hinzufügen und warten, dass dieses Ereignis ausgelöst wird, da ich die Konnektivität des Clients mit sinon verspottet habe. Also gibt es keine echte Verbindung. Wie kann ich dieses Nachrichtenereignis manuell ausgeben und sehen, ob onMessageReceived von messageReceivedCallBack aufgerufen wurde? Ich bin neu in Unit-Tests in Javascript. Zur Zeit verwende ich Mocha und Sinon für meine Testanforderungen.

Bitte um Rat.

+0

Ihr Testcode Zugang zu muss 'this.client' und' messageReceivedCallBack'. Ist das der Fall? – robertklep

+0

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

Antwort

2

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(); 
    }); 

}); 
+0

Awesome Lösung Kumpel! :) – mayooran