Reputation: 1
I am having problems while trying to test effects in my Angular 11 project. I use the karma runner. It would seem that when I dispatch an action in my tests, the effects does't seem to respond to it.
import { TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { provideMockActions } from '@ngrx/effects/testing';
import {
SimpleActionTypes,
} from '../actions/simple.action';
import {SimpleEffects} from './simple.effect';
import {MockStore, provideMockStore} from '@ngrx/store/testing';
import {Store} from '@ngrx/store';
describe('SimpleEffects', () => {
let actions$: any;
let effects: SimpleEffects;
let store: MockStore<Store>;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
SimpleEffects,
provideMockActions(() => actions$),
provideMockStore() ,
],
});
store = TestBed.inject(MockStore);
effects = TestBed.inject(SimpleEffects);
});
it('should be created', () => {
expect(effects).toBeTruthy();
});
it('should fire with a default price', (done) => {
// Mock the action that we use to activate the effect
actions$ = of(SimpleActionTypes.UnavailablePrice);
// Subscribe to the effect
effects.getPriceAfterLocalCartUpdate.subscribe((res) => {
// the expected results verification
expect(res).toEqual(SimpleActionTypes.ComputePrice);
// And all done !
done();
});
});
});
I have tried many ways to enter the subscribe part of my effect (using marbles hot cold ...), but it doesn't seem to work. I have a failure indicating :
"SimpleEffects should fire with a default price FAILED
Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL)"
The micro project is hosted here : https://github.com/Ushelajyan/simple-ngrx-testing-effects
Thank you in advance for your help.
Upvotes: 0
Views: 2045
Reputation: 5482
You override actions$
within your test (it
-block). Unfortunately the TestBed.configureTestingModule()
gets executed inside a beforeEach
block, which happens right before the it
-block gets executed.
import { TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { provideMockActions } from '@ngrx/effects/testing';
import {
SimpleActionTypes,
} from '../actions/simple.action';
import {SimpleEffects} from './simple.effect';
import {MockStore, provideMockStore} from '@ngrx/store/testing';
import {Store} from '@ngrx/store';
describe('SimpleEffects', () => {
let store: MockStore<Store>;
const createEffects = (actions$) => {
TestBed.configureTestingModule({
providers: [
SimpleEffects,
provideMockActions(() => actions$),
provideMockStore() ,
],
});
store = TestBed.inject(MockStore);
return TestBed.inject(SimpleEffects);
};
it('should be created', () => {
const effects = createEffects(of(undefined));
expect(effects).toBeTruthy();
});
it('should fire with a default price', (done) => {
// Mock the action that we use to activate the effect
const actions$ = of(SimpleActionTypes.UnavailablePrice);
// Create the effect with your given mock
const effects = createEffects(actions$)
effects.getPriceAfterLocalCartUpdate.subscribe((res) => {
// the expected results verification
expect(res).toEqual(SimpleActionTypes.ComputePrice);
// And all done !
done();
});
});
});
This should do the trick.
I added a createEffect
function that configures your TestBed
properly with the given actions$
mock and returns a new instance of SimpleEffects
.
This instance can then be used to subscribe to its defined effects.
Upvotes: 1