我正在使用 Nodejs、RxJS 和 Typescript 开发应用。
应用程序有一个返回字符串的 Observable 的函数
myObsFunction() : Observable<string> {
... do stuff
}
我希望能够做一个简单的测试来检查当我订阅这个函数时我得到了预期的字符串。我正在使用 chai 和 mocha 所以我写了下面的测试用例
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)
)
});
});
不幸的是,这个测试用例并没有像我预期的那样工作。即使在出现错误的情况下,它也始终表现得像已成功通过一样。我在 onCompleted
函数中编写的 expect
检查不会发出任何信号,即使 expectedString 不等于 receivedString 也是如此。 onCompleted
函数实际上被执行了(我可以看到这只是在 onCompleted
函数中添加了一条 console.log
指令)但是 expect 没有发出信号有错有错
有没有什么方法可以运行如此简单的测试,而不必开始使用调度程序和更复杂的机制?
最佳答案
测试逻辑看起来很合理,这是一个使用 mocha 和 chai 的工作示例。
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>
当 observable 从不触发时的误报
如果可观察对象从不触发,我遇到的一件事是误报。这是我用来克服该问题的一些辅助函数。请注意,take(1)
可确保触发已完成的事件,即使可观察对象本身并未完成。
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>
关于node.js - 使用 chai 和 mocha 在 nodejs 中对 Observable 结果进行简单测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47365114/