测试发出延迟动作或不发出任何东西的 NGRX 效果
Testing NGRX effect that emits action with delay OR does not emit anything
我有一个 NGRX 效果 - 根据状态 - 发出延迟的动作或什么都不发出。
我想写一个测试,涵盖这两种情况。
效果是这样的:
myEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyAction),
filter(state => state.foo === false),
delay(4000),
map(state => myOtherAction())
)
);
测试应该发出延迟的otherAction工作正常:
describe('emit my action', () => {
const action = MyAction();
it('should return a stream with myOtherAction', () => {
const scheduler = getTestScheduler();
scheduler.run(helpers => {
// build the observable with the action
actions = hot('-a', { a: action });
// define what is the expected outcome of the effect
const expected = {
b: MyOtherAction()
};
helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
});
});
});
但我不知道如何测试其他状态,它应该不发出另一个动作(流长度为零):
it('should return an empty stream', () => {
store.setState({
myFeature: {
foo: true
}
});
// ???
});
请帮忙:)
这很难做到,因为过滤器会阻止效果 return 成为可观察的。
选项 1:
// 无论你在哪里调度 MyAction,只有当 foo 属性 在创建的 action
上为真时才调度它
选项 2:
// 将效果的结构改为return空
import { EMPTY } from 'rxjs';
....
myEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyAction),
delay(4000),
map(state => state.foo ? myOtherAction() : EMPTY)
)
);
测试:
import { EMPTY } from 'rxjs';
....
describe('emit my action', () => {
const action = MyAction();
action.foo = false; // set foo property to false
it('should return a stream with myOtherAction', () => {
const scheduler = getTestScheduler();
scheduler.run(helpers => {
// build the observable with the action
actions = hot('-a', { a: action });
// define what is the expected outcome of the effect
const expected = {
b: EMPTY // assert now it is empty
};
helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
});
});
})
由于 AliF50 的提示,我用“Noop Action”(= 没有任何侦听器的正常操作)替换了链中的 filter
(它阻止 Observable 发射)。因此,我没有检查过滤器中的 foo
属性,而是 return 地图中的 noopAction
,当 foo 为真时,otherAction 为假时。
效果:
myEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyAction),
//filter(state => state.foo === false),
delay(4000),
map(state => state.foo !== false ? noopAction() : myOtherAction())
)
);
测试:
describe('emit my action', () => {
const action = MyAction();
it('should return a stream with myOtherAction', () => {
const scheduler = getTestScheduler();
scheduler.run(helpers => {
// build the observable with the action
actions = hot('-a', { a: action });
// define what is the expected outcome of the effect
const expected = {
b: MyOtherAction()
};
helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
});
});
it('should return a stream with noop action as foo is true', () => {
store.setState({
myFeature: {
foo: true
}
});
const scheduler = getTestScheduler();
scheduler.run(helpers => {
// build the observable with the action
actions = hot('-a', { a: action });
// define what is the expected outcome of the effect
const expected = {
b: NoopAction()
};
helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
});
});
});
我有一个 NGRX 效果 - 根据状态 - 发出延迟的动作或什么都不发出。 我想写一个测试,涵盖这两种情况。
效果是这样的:
myEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyAction),
filter(state => state.foo === false),
delay(4000),
map(state => myOtherAction())
)
);
测试应该发出延迟的otherAction工作正常:
describe('emit my action', () => {
const action = MyAction();
it('should return a stream with myOtherAction', () => {
const scheduler = getTestScheduler();
scheduler.run(helpers => {
// build the observable with the action
actions = hot('-a', { a: action });
// define what is the expected outcome of the effect
const expected = {
b: MyOtherAction()
};
helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
});
});
});
但我不知道如何测试其他状态,它应该不发出另一个动作(流长度为零):
it('should return an empty stream', () => {
store.setState({
myFeature: {
foo: true
}
});
// ???
});
请帮忙:)
这很难做到,因为过滤器会阻止效果 return 成为可观察的。
选项 1: // 无论你在哪里调度 MyAction,只有当 foo 属性 在创建的 action
上为真时才调度它选项 2: // 将效果的结构改为return空
import { EMPTY } from 'rxjs';
....
myEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyAction),
delay(4000),
map(state => state.foo ? myOtherAction() : EMPTY)
)
);
测试:
import { EMPTY } from 'rxjs';
....
describe('emit my action', () => {
const action = MyAction();
action.foo = false; // set foo property to false
it('should return a stream with myOtherAction', () => {
const scheduler = getTestScheduler();
scheduler.run(helpers => {
// build the observable with the action
actions = hot('-a', { a: action });
// define what is the expected outcome of the effect
const expected = {
b: EMPTY // assert now it is empty
};
helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
});
});
})
由于 AliF50 的提示,我用“Noop Action”(= 没有任何侦听器的正常操作)替换了链中的 filter
(它阻止 Observable 发射)。因此,我没有检查过滤器中的 foo
属性,而是 return 地图中的 noopAction
,当 foo 为真时,otherAction 为假时。
效果:
myEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyAction),
//filter(state => state.foo === false),
delay(4000),
map(state => state.foo !== false ? noopAction() : myOtherAction())
)
);
测试:
describe('emit my action', () => {
const action = MyAction();
it('should return a stream with myOtherAction', () => {
const scheduler = getTestScheduler();
scheduler.run(helpers => {
// build the observable with the action
actions = hot('-a', { a: action });
// define what is the expected outcome of the effect
const expected = {
b: MyOtherAction()
};
helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
});
});
it('should return a stream with noop action as foo is true', () => {
store.setState({
myFeature: {
foo: true
}
});
const scheduler = getTestScheduler();
scheduler.run(helpers => {
// build the observable with the action
actions = hot('-a', { a: action });
// define what is the expected outcome of the effect
const expected = {
b: NoopAction()
};
helpers.expectObservable(effects.myEffect$).toBe('- 4000ms b', expected);
});
});
});