admin管理员组文章数量:1123712
I defined a number of effects, whose first one has dispatch: false
:
readonly abort$ = createEffect(() => {
return this.actions.pipe(
ofType(myActions.abort),
tap( (action) => {
console.log('request abort for', action.reason.toString());
...
}),
catchError(MyEffects.catchServiceError)
)
}, { dispatch: false } );
I defined unit tests like following:
describe('MyBankEffects', () => {
let effects: MyBankEffects;
let action$: Observable<Action> = new Observable<Action>();
beforeEach( () => {
TestBed.configureTestingModule({
imports: [
EffectsModule.forFeature(MyBankEffects)
],
providers: [
provideMockActions( () => action$),
]
});
effects = TestBed.inject(MyBankEffects);
});
it('should navigate to abort', (done) => {
action$ = of(myActions.abort({ reason: AbortReason.TIMEOUT }));
effects.abort$.pipe(take(1)).subscribe({
next: () => {
expect(...);
},
error: e => done.fail(e),
complete: () => {
expect(...);
done();
}
});
});
In the next executed test, whichever it is, the first effect is executed again (without any mocks defined in its specific test), before running the test itself. It looks like the action dispatched in the test above, remains "in queue", and is consumed by the following test execution.
Anyone can explain what happens, and how can I purge the action at the end of the single test?
I defined a number of effects, whose first one has dispatch: false
:
readonly abort$ = createEffect(() => {
return this.actions.pipe(
ofType(myActions.abort),
tap( (action) => {
console.log('request abort for', action.reason.toString());
...
}),
catchError(MyEffects.catchServiceError)
)
}, { dispatch: false } );
I defined unit tests like following:
describe('MyBankEffects', () => {
let effects: MyBankEffects;
let action$: Observable<Action> = new Observable<Action>();
beforeEach( () => {
TestBed.configureTestingModule({
imports: [
EffectsModule.forFeature(MyBankEffects)
],
providers: [
provideMockActions( () => action$),
]
});
effects = TestBed.inject(MyBankEffects);
});
it('should navigate to abort', (done) => {
action$ = of(myActions.abort({ reason: AbortReason.TIMEOUT }));
effects.abort$.pipe(take(1)).subscribe({
next: () => {
expect(...);
},
error: e => done.fail(e),
complete: () => {
expect(...);
done();
}
});
});
In the next executed test, whichever it is, the first effect is executed again (without any mocks defined in its specific test), before running the test itself. It looks like the action dispatched in the test above, remains "in queue", and is consumed by the following test execution.
Anyone can explain what happens, and how can I purge the action at the end of the single test?
Share Improve this question asked yesterday HilbertHilbert 335 bronze badges1 Answer
Reset to default 0This happens because the action observable(action$) remains active across the test cases, and the dispatched action (myActions.abort) is not being completely cleaned up after the test.
You can ensure that actions are properly consumed and the action$ observable is reset for each test by:
Using new instance of action$ for each test.
Completing the observable after the test.
Cleaning up subscriptions or ensuring that the effect itself unsubscribes.
import { TestBed } from '@angular/core/testing'; import { provideMockActions } from '@ngrx/effects/testing'; import { Observable, of, Subject } from 'rxjs'; import { take } from 'rxjs/operators'; import { MyBankEffects } from './my-bank.effects'; import * as myActions from './my-bank.actions'; import { AbortReason } from './abort-reason.enum'; describe('MyBankEffects', () => { let effects: MyBankEffects; let action$: Subject<Action>; beforeEach(() => { action$ = new Subject<Action>(); TestBed.configureTestingModule({ imports: [ EffectsModule.forFeature([MyBankEffects]) ], providers: [ provideMockActions(() => action$), ], }); effects = TestBed.inject(MyBankEffects); }); afterEach(() => { // Complete the observable after each test to avoid cross-contamination. action$.complete(); }); it('should navigate to abort', (done) => { const reason = AbortReason.TIMEOUT; action$.next(myActions.abort({ reason })); effects.abort$.pipe(take(1)).subscribe({ next: () => { expect(true).toBe(true); // Replace with your actual assertion. }, error: (e) => done.fail(e), complete: () => { expect(true).toBe(true); // Replace with your actual assertion. done(); }, }); }); });
Key Changes:
Subject for action$: This allows to emit actions(action$.next(...)) and complete the stream after each test(action$.complete()).
Reset between Tests: afterEach ensures the Subject is completed, preventing leftover actions from being processed by subsequent tests.
Avoid stale Observables: take(1) operator ensures that the effect only proccesses one action per test case.
本文标签: Angular unit test of ngrxeffectsactions not purgedStack Overflow
版权声明:本文标题:Angular unit test of @ngrxeffects, actions not purged - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736586765a1945023.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论