Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(store): remove afterEach hook in mock store #3245

Merged
merged 8 commits into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 0 additions & 103 deletions modules/store/testing/spec/mock_store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,106 +516,3 @@ describe('Refreshing state', () => {
expect(getTodoItems('li')[0].nativeElement.textContent.trim()).toBe('bbb');
});
});

describe('Cleans up after each test', () => {
const selectData = createSelector(
(state: any) => state,
(state) => state.value
);

it('should return the mocked selectors value', (done: any) => {
TestBed.configureTestingModule({
providers: [
provideMockStore({
initialState: {
value: 100,
},
selectors: [{ selector: selectData, value: 200 }],
}),
],
});

const store = TestBed.inject(Store);
store.pipe(select(selectData)).subscribe((v) => {
expect(v).toBe(200);
done();
});
});

it('should return the real value', (done: any) => {
TestBed.configureTestingModule({
imports: [
StoreModule.forRoot({} as any, {
initialState: {
value: 300,
},
}),
],
});

const store = TestBed.inject(Store);
store.pipe(select(selectData)).subscribe((v) => {
expect(v).toBe(300);
done();
});
});
});
cedricduffournet marked this conversation as resolved.
Show resolved Hide resolved

describe('Resets selectors after each test', () => {
const selectorUnderTest = createSelector(
(state: any) => state,
(state) => state.value
);
let shouldSetMockStore = true;

function setupModules(isMock: boolean) {
if (isMock) {
TestBed.configureTestingModule({
providers: [
provideMockStore({
initialState: {
value: 100,
},
selectors: [{ selector: selectorUnderTest, value: 200 }],
}),
],
});
} else {
TestBed.configureTestingModule({
imports: [
StoreModule.forRoot({} as any, {
initialState: {
value: 300,
},
}),
],
});
}
}

/**
* Tests run in random order, so that's why we have two attempts (one runs
* before another - in any order) and whichever runs the test first would
* setup MockStore and override selector. The next one would use the regular
* Store and verifies that the selector is cleared/reset.
*/
it('should reset selector - attempt one', (done: any) => {
setupModules(shouldSetMockStore);
const store: Store<{}> = TestBed.inject(Store);
store.select(selectorUnderTest).subscribe((v) => {
expect(v).toBe(shouldSetMockStore ? 200 : 300);
shouldSetMockStore = false;
done();
});
});

it('should reset selector - attempt two', (done: any) => {
setupModules(shouldSetMockStore);
const store: Store<{}> = TestBed.inject(Store);
store.select(selectorUnderTest).subscribe((v) => {
expect(v).toBe(shouldSetMockStore ? 200 : 300);
shouldSetMockStore = false;
done();
});
});
});
13 changes: 0 additions & 13 deletions modules/store/testing/src/mock_store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Inject, Injectable } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { Observable, BehaviorSubject } from 'rxjs';
import {
Action,
Expand All @@ -15,18 +14,6 @@ import { MockState } from './mock_state';
import { MockSelector } from './mock_selector';
import { MOCK_SELECTORS } from './tokens';

if (typeof afterEach === 'function') {
afterEach(() => {
try {
const mockStore: MockStore | undefined = TestBed.inject(MockStore);
if (mockStore) {
mockStore.resetSelectors();
}
// eslint-disable-next-line no-empty
} catch {}
});
}

type OnlyMemoized<T, Result> = T extends string | MemoizedSelector<any, any>
? MemoizedSelector<any, Result>
: T extends MemoizedSelectorWithProps<any, any, any>
Expand Down
1 change: 1 addition & 0 deletions projects/example-app/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ module.exports = {
moduleNameMapper: {
tslib: '<rootDir>../../node_modules/tslib/tslib.es6.js',
},
testRunner: 'jest-circus/runner',
};
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('Login Page', () => {
};
instance.form.setValue(credentials);

spyOn(instance.submitted, 'emit');
jest.spyOn(instance.submitted, 'emit');
instance.submit();

expect(instance.submitted.emit).toHaveBeenCalledWith(credentials);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('Login Page', () => {
instance = fixture.componentInstance;
store = TestBed.inject(MockStore);

spyOn(store, 'dispatch');
jest.spyOn(store, 'dispatch');
});

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('AuthEffects', () => {
routerService = TestBed.inject(Router);
dialog = TestBed.inject(MatDialog);

spyOn(routerService, 'navigate').and.callThrough();
jest.spyOn(routerService, 'navigate');
});

describe('login$', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('Collection Page', () => {
instance = fixture.componentInstance;
store = TestBed.inject(MockStore);

spyOn(store, 'dispatch');
jest.spyOn(store, 'dispatch');
});

it('should compile', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('Find Book Page', () => {
instance = fixture.componentInstance;
store = TestBed.inject(MockStore);

spyOn(store, 'dispatch');
jest.spyOn(store, 'dispatch');
});

it('should compile', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('Selected Book Page', () => {
instance = fixture.componentInstance;
store = TestBed.inject(MockStore);

spyOn(store, 'dispatch');
jest.spyOn(store, 'dispatch');
});

it('should compile', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { MemoizedSelector } from '@ngrx/store';
import { Store, StoreModule } from '@ngrx/store';
import { provideMockStore, MockStore } from '@ngrx/store/testing';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
Expand Down Expand Up @@ -96,3 +97,51 @@ describe('AppComponent', () => {
//#enddocregion mockSelector
});
});

//#docregion resetMockSelector
describe('AppComponent reset selectors', () => {
let store: MockStore;

afterEach(() => {
store?.resetSelectors();
});

it('should return the mocked value', (done: any) => {
TestBed.configureTestingModule({
providers: [
provideMockStore({
selectors: [
{
selector: selectBooks,
value: [
{
id: 'mockedId',
volumeInfo: {
title: 'Mocked Title',
authors: ['Mocked Author'],
},
},
],
},
],
}),
],
});

timdeschryver marked this conversation as resolved.
Show resolved Hide resolved
store = TestBed.inject(MockStore);

store.select(selectBooks).subscribe((mockBooks) => {
expect(mockBooks).toEqual([
{
id: 'mockedId',
volumeInfo: {
title: 'Mocked Title',
authors: ['Mocked Author'],
},
},
]);
done();
});
});
});
//#enddocregion resetMockSelector
6 changes: 2 additions & 4 deletions projects/ngrx.io/content/guide/store/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,9 @@ Usage:

In this example based on the [walkthrough](guide/store/walkthrough), we mock the `selectBooks` selector by using `overrideSelector`, passing in the `selectBooks` selector with a default mocked return value of an array of books. Similarly, we mock the `selectBookCollection` selector and pass the selector together with another array. In the test, we use `setResult()` to update the mock selectors to return new array values, then we use `MockStore.refreshState()` to trigger an emission from the `selectBooks` and `selectBookCollection` selectors.

<div class="alert is-helpful">

**Note:** `MockStore` will reset all of the mocked selectors after each test (in the `afterEach()` hook) by calling the `MockStore.resetSelectors()` method.
You can reset selectors by calling the `MockStore.resetSelectors()` method in the `afterEach()` hook.

</div>
<code-example header="src/app/app.component.spec.ts (Reset Mock Selector) " path="store-walkthrough/src/app/tests/app.component.1.spec.ts" region="resetMockSelector"></code-example>

Try the <live-example name="testing-store"></live-example>.

Expand Down