如何编写Jasmine测试来测试debounce运算符的可观察量?我已经关注了这篇博文,了解了应该如何测试的原则,但它似乎没有用.
下面是我用来创建observable的工厂:
import Rx from "rx/dist/rx.all";
import DOMFactory from "../utils/dom-factory";
import usernameService from "./username.service";
function createUsernameComponent(config) {
const element = DOMFactory(config);
const username = Rx.Observable
.fromEvent(element.find('input'), 'input')
.pluck('target', 'value')
.startWith(config.value);
const isAvailable = username
.debounce(500)
.tap(() => console.info('I am never called!'))
.flatMapLatest(usernameService.isAvailable)
.startWith(false);
const usernameStream = Rx.Observable.combineLatest(username, isAvailable)
.map((results) => {
const [username, isAvailable] = results;
return isAvailable ? username : ''
})
.distinctUntilChanged();
return Object.freeze({
stream: usernameStream,
view: element
});
}
export default createUsernameComponent;
Run Code Online (Sandbox Code Playgroud)
请注意,tap测试员从不调用运算符.但是,如果我在浏览器上运行此代码,它将正确执行.
以下是我在测试中的尝试:
import Rx from "rx/dist/rx.all";
import Username from "./username.component";
import DataItemBuilder from "../../../test/js/utils/c+j-builders";
import usernameService from "./username.service"
describe('Username Component', () => {
let input, username;
beforeEach(() => {
const usernameConfig = DataItemBuilder.withName('foo')
.withPrompt('label').withType('text').build();
const usernameComponent = Username(usernameConfig);
usernameComponent.stream.subscribe(value => username = value);
input = usernameComponent.view.find('input');
});
it('should set to a valid username after debounce', () => {
const scheduler = injectTestSchedulerIntoDebounce();
scheduler.scheduleRelative(null, 1000, () => {
doKeyUpTest('abcddd', 'abcdd');
scheduler.stop();
});
scheduler.start();
scheduler.advanceTo(1000);
});
function injectTestSchedulerIntoDebounce() {
const originalOperator = Rx.Observable.prototype.debounce;
const scheduler = new Rx.TestScheduler();
spyOn(Rx.Observable.prototype, 'debounce').and.callFake((dueTime) => {
console.info('The mocked debounce is never called!');
if (typeof dueTime === 'number') {
return originalOperator.call(this, dueTime, scheduler);
}
return originalOperator.call(this, dueTime);
});
return scheduler;
}
function doKeyUpTest(inputValue, expectation) {
input.val(inputValue);
input.trigger('input');
expect(username).toBe(expectation);
}
});
Run Code Online (Sandbox Code Playgroud)
当我运行测试时,假的debounce永远不会被调用.username一旦我能够超越,我打算嘲笑这项服务debounce.
在您的测试代码中,您将触发函数内的输入事件scheduleRelative。这不起作用,因为您在进行更改之前提前了 1000 毫秒。然后,去抖动器会等待 500 毫秒来对调用进行去抖动isAvailable,但您已经停止了调度程序,因此之后时间不会提前。
你应该做的是:在提前调度程序时间之前触发输入事件,或者在函数中触发输入事件scheduleRelative的时间<= 500ms,然后在函数内scheduleRelative触发1000ms,你必须使用expect预期的输出调用函数,然后停止调度程序。
它应该看起来像这样:
it('should set to a valid username after debounce', () => {
const scheduler = injectTestSchedulerIntoDebounce();
scheduler.scheduleRelative(null, 500, () => {
input.val(inputValue);
input.trigger('input');
});
scheduler.scheduleRelative(null, 1000, () => {
expect(username).toBe(expectation);
scheduler.stop();
});
scheduler.start();
scheduler.advanceTo(1000);
});
Run Code Online (Sandbox Code Playgroud)
除此之外,我对scheduleAbsolute替代品有更好的经验scheduleRelative,因为它不那么令人困惑。
| 归档时间: |
|
| 查看次数: |
3331 次 |
| 最近记录: |