2016-05-24 6 views
0

以下のコードがあります。イベントエミッタによってバインドされていないイベントのユニットテスト

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クライアントがメッセージイベントを発行したときに発生する匿名関数があります。私はこれをコントロールすることはできません。つまり、これをイベントエミッタに結びつけた私のことではありません。また、私はタイマーを追加することはできませんし、このイベントが発生するのを待つ私はsinonを使用してクライアントの接続を嘲笑している。したがって、実際の接続はありません。では、このメッセージイベントを手動で発行して、messageReceivedCallBackのonMessageReceivedが呼び出されたかどうかを確認します。私はJavascriptで単体テストに慣れています。現在、私はユニットテストのためにモカとサイロンを使用しています。

アドバイスをしてください。

+0

あなたのテストコードがアクセスする必要があります'this.client'と' messageReceivedCallBack'です。それは事実ですか? – robertklep

+0

this.clientには、 "mqtt.connect"という行から値が割り当てられます。だから私は自分のスタブを返す。私は内部でコードをテストできるように、このイベントをどのように発火させることができるかを知る必要があります。私はconnectメソッドをスタブしているので、 "message"イベントは自動的に発生しません。私はそれを手動で発射する必要があります。私はどのように分かっていない:( – mayooran

答えて

2

大きな免責事項まず、TypeScriptもアプリケーションの内部もわからないので、以下のものはすぐに使用できない可能性があります。ただし、この種のテストを実装する方法については、いくつかのアイデアを提供する場合があります。 messageReceivedCallBackがどこから来ていることは明らかではない、あなたのコードでは

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

は、私はあなたのクライアントコード(コードのthatsをテストする必要があります)を抽象化。 Sinonからアクセスできる必要があるため、インポート可能なモジュールに入れておく必要があります(ただし、これは、TSがこれを行うかどうかわからない require()などのインポートがキャッシュされているという事実に依存します)。最後に

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

、テスト自体:

は、ここで私が使用し、簡単なモックです。それはいろいろなことを行う必要があるので、それはかなり精巧です:

  • 様々な機能とコールバック
  • は、テスト環境
を設定し、元の MqttClient
  • とスタブを置き換えるために使用され EventEmitterサブクラスを作成します

    コード:

    // 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

    恐ろしい解決策のメイト!:) – mayooran

    関連する問題