2017-11-18 178 views
1

我正在使用Nodejs,RxJS和Typescript开发应用程序。使用chai和mocha在nodejs中观察结果的简单测试

应用程序有它返回一个可观察的字符串

myObsFunction() : Observable<string> { 
... do stuff 
} 

我希望能够做一个简单的测试来检查,当我订阅了这个功能我得到预期的字符串的函数。我使用摩卡,所以我写了下面的测试情况

import { expect } from 'chai'; 
import 'mocha'; 

import {myObsFunction} from './my-source-file'; 

describe('myObsFunction function',() => { 

    it('check myObsFunction',() => { 
     const expectedString = 'abc'; 
     let receivedString: string; 
     myObsFunction().subscribe(
      data => receivedString = data, 
      error => console.error(error), 
      () => expect(receivedString).to.equal(expectedString) 
     ) 
    }); 

}); 

不幸被我预期这个测试用例不起作用。它始终表现为即使在出现错误的情况下也能成功通过。 expect检查我已经写在onCompleted函数不会发出任何信号,即使expectedString不等于receivedString。实际执行的onCompleted功能(我可以看到这个刚刚加入的onCompleted功能console.log指令),但预计不会发出信号时出现错误

有没有什么办法,而无需启动运行这样简单的测试任何错误使用调度程序和更复杂的机制?

+1

看来'myObsFunction'异步运行,所以你需要使用''的回调it'到done'信号其执行结束。 –

回答

1

测试逻辑看起来很合理,这里是摩卡和柴的一个工作示例。

console.clear() 
 
const Observable = Rx.Observable 
 
mocha.setup('bdd'); 
 
const assert = chai.assert; 
 
const should = chai.should(); 
 
const expect = chai.expect; 
 
const done = mocha.done; 
 

 

 
const myObsFunction =() => Observable.of('xyz'); 
 
const myAsyncObsFunction =() => Observable.timer(500).mapTo('xyz'); 
 

 
describe('RxJs Observable Test Examples', function() { 
 

 
    it('should test the observable succeeds', function() { 
 
    const expectedString = 'xyz'; 
 
    let receivedString: string; 
 
    myObsFunction().subscribe(
 
     data => receivedString = data, 
 
     error => console.error(error), 
 
    () => { 
 
     expect(receivedString).to.equal(expectedString); 
 
     } 
 
    ) 
 
    }); 
 

 
    it('should test the observable fails', function() { 
 
    const expectedString = 'abc'; 
 
    let receivedString: string; 
 
    myObsFunction().subscribe(
 
     data => receivedString = data, 
 
     error => console.error(error), 
 
    () => { 
 
     expect(receivedString).to.equal(expectedString); 
 
     } 
 
    ) 
 
    }); 
 

 
    it('should test the async observable succeeds', function (done) { 
 
    const expectedString = 'xyz'; 
 
    let receivedString: string; 
 
    myAsyncObsFunction().subscribe(
 
     data => receivedString = data, 
 
     error => console.error(error), 
 
    () => { 
 
     //expect(receivedString).to.equal(expectedString); 
 
     if (receivedString !== expectedString) { 
 
      return done(new Error("Failed match")); 
 
     } else { 
 
      return done(); 
 
     } 
 
     } 
 
    ) 
 
    }); 
 

 
    it('should test the async observable fails', function (done) { 
 
    const expectedString = 'abc'; 
 
    let receivedString: string; 
 
    myAsyncObsFunction().subscribe(
 
     data => receivedString = data, 
 
     error => console.error(error), 
 
    () => { 
 
     //expect(receivedString).to.equal(expectedString); 
 
     if (receivedString !== expectedString) { 
 
      return done(new Error("Failed match")); 
 
     } else { 
 
      return done(); 
 
     } 
 
     } 
 
    ) 
 
    }); 
 
}); 
 

 
mocha.run();
<link href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.min.css" rel="stylesheet"/> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script> 
 
<div id="mocha"></div>


误报当观察到的永远不会触发

有一件事我遇到了误报,如果观察到永远不会触发。这是我用来解决这个问题的一些辅助函数。请注意,take(1)可确保已完成的事件被触发,即使observable本身没有完成。

console.clear() 
 
const Observable = Rx.Observable 
 
mocha.setup('bdd'); 
 
const assert = chai.assert; 
 
const should = chai.should(); 
 
const expect = chai.expect; 
 

 
const subscribeAndTestValue = function (observable: Observable<any>, expected: any): string { 
 
    let fail = ''; 
 
    let wasSubscribed = false; 
 
    const sub = observable 
 
    .take(1) 
 
    .subscribe(
 
     (result) => { 
 
     if (result !== expected) { 
 
      fail = 'Subscription result does not match expected value'; 
 
     } 
 
     wasSubscribed = true; 
 
     }, 
 
     (error) => { 
 
     fail = 'Subscription raised an error'; 
 
     }, 
 
     (/*completed*/) => { 
 
     // When testing a single value, 
 
     // need to check that the subscription was activated, 
 
     // otherwise the expected value is never tested 
 
     if (!wasSubscribed) { 
 
      fail = 'Subscription produced no results'; 
 
     } 
 
     } 
 
    ); 
 
    sub.unsubscribe(); 
 
    return fail; 
 
} 
 

 
const subscribeAndTestNoDataEmitted = function (observable: Observable<any>): string { 
 
    let fail; 
 
    let wasSubscribed = false; 
 
    const sub = observable 
 
    .subscribe(
 
     (result) => { 
 
     wasSubscribed = true; 
 
     }, 
 
     (error) => { 
 
     fail = 'Subscription raised an error'; 
 
     }, 
 
     (/*completed*/) => { 
 
     if (wasSubscribed) { 
 
      fail = 'Subscription produced values when none were expected'; 
 
     } 
 
     } 
 
    ); 
 
    sub.unsubscribe(); 
 
    return fail; 
 
} 
 

 
const emptyObservable = Observable.empty(); 
 
const nonCompletingObservable = Observable.interval(1000); 
 
const emittingObservable = Observable.of('abc'); 
 

 
describe('RxJs Observable Test Examples', function() { 
 

 
    it('should test the observable fires', function() { 
 
    const expectedString = 'xyz'; 
 
    const failed = subscribeAndTestValue(emptyObservable, expectedString); 
 
    expect(failed).to.equal('Subscription produced no results'); 
 
    }); 
 

 
    it('should test first observable value of a non-completing observable', function() { 
 
    const expectedString = '0'; 
 
    const failed = subscribeAndTestValue(nonCompletingObservable, expectedString); 
 
    expect(failed).to.equal(''); 
 
    }); 
 

 
    it('should test the observable does not fire', function() { 
 
    const expectedString = 'xyz'; 
 
    const failed = subscribeAndTestNoDataEmitted(emittingObservable, expectedString); 
 
    expect(failed).to.equal('Subscription produced values when none were expected'); 
 
    }); 
 
    
 
}); 
 

 
mocha.run();
<link href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.min.css" rel="stylesheet"/> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script> 
 
<div id="mocha"></div>

+0

谢谢,答案是正确的,并帮助我继续前进。对于那些使用Typescript和当前最新版本的Mocha(4.0.1)的用户来说,只有一条评论。在这种情况下,您可以通过'import'mocha';'导入Mocha,然后使用'done' – Picci

相关问题