Mocking NgRx store с помощью Spectator
Я пытаюсь писать модульные тесты вместе с Angular, Jest и Spectator. Щас борюсь с издевательским магазином NgRx. Я получаю сообщение об ошибке "Нет поставщика для MockStore" при попытке получить экземпляр предоставленного NgRxMockStore
из экземпляра Spectator.
Я прочитал документацию NgRx, касающуюся имитации и модульных тестов, и я могу имитировать хранилище NgRx без использования Spectator, читая документацию, я пробовал поискать в Google помощь, но, похоже, не могу найти примеры совместных издевательств над хранилищем NgRx со Spectator, и я оставил сообщение на NgRx/store Gitter, чтобы узнать, может ли кто-нибудь мне помочь.
Вот как выглядит мой код:
let component: MyComponent;
let spectator: Spectator<MyComponent>;
let mockStore: MockStore<selectors.AppState>;
let mockUsernameSelector: MemoizedSelector<AppState, string>;
const createComponent = createComponentFactory({
component: MyComponent,
componentProviders: [
provideMockStore(),
],
shallow: true,
detectChanges: false,
});
beforeEach(() => {
spectator = createComponent();
component = spectator.component;
mockStore = spectator.inject<MockStore<selectors.AppState>>(MockStore);
mockUsernameSelector = mockStore.overrideSelector(selectors.selectUserName, 'Bob');
});
Но, как я уже сказал, как только я попытаюсь получить экземпляр MockStore
от зрителя через spectator.inject
(тоже пробовал spectator.get
), Я получаю ошибку "Нет провайдера для MockStore". Я также попытался предоставитьMockStore
как это:
const createComponent = createComponentFactory({
component: MyComponent,
componentProviders: [
mockProvider(MockStore, provideMockStore()),
],
shallow: true,
detectChanges: false,
});
Но тогда я, очевидно, получаю ошибку "Нет провайдера для Магазина".
Может быть, здесь кто-нибудь сможет мне помочь? Заранее спасибо!
3 ответа
У меня была такая же проблема, похоже, это работает для меня:
В setup-jest.ts
Я определил глобальные инъекции с общим тестовым импортом и поставщиком для магазина, использующего provideMockStore
с начальным состоянием:
import { provideMockStore } from '@ngrx/store/testing';
let initialState = MockStoreInitialState; // constant built from all reducers initial states
defineGlobalsInjections({
imports: [
MaterialModule,
NoopAnimationsModule,
ReactiveFormsModule,
FormsModule,
SharedModule,
TranslateTestingModule.withTranslations({ en: require('./assets/i18n/en.json') }),
],
providers: [provideMockStore({ initialState })],
});
Затем при тестировании компонентов я использую MockStore и шпионы:
describe('SampleCardComponent', () => {
let mockStore;
let dispatchSpy;
let spectator: Spectator<SampleCardComponent>;
const createComponent = createTestComponentFactory({
component: SampleCardComponent,
mocks: [ExperimentTimePipe],
});
beforeEach(() => {
spectator = createComponent({
props: { sampleHolder: SAMPLE_MOCK },
});
mockStore = spectator.get(MockStore);
dispatchSpy = jest.spyOn(mockStore, 'dispatch');
});
test('should create', () => {
expect(spectator).toBeTruthy();
});
test('should call editSample function', () => {
const handleEditSpy = jest.spyOn(spectator.component, 'handleEdit');
spectator.click('.button-edit');
spectator.detectChanges();
expect(handleEditSpy).toHaveBeenCalled();
expect(dispatchSpy).toHaveBeenCalledTimes(1);
expect(dispatchSpy).toHaveBeenCalledWith({//...actionObject})
});
});
Честно говоря, понятия не имею, лучший ли это способ, но он работает. Если вы видите способ улучшить это, я буду рад это услышать.
Вы можете получить его, просто используя spectator.inject(MockStore).
И не забудьте добавить фиктивное начальное состояние в providerMockStore({ initialState })
import { Spectator, createComponentFactory } from '@ngneat/spectator';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { mockInitialState } from 'src/mocks/state/app-state.mock';
import { AppComponent } from './app.component';
import { AppState } from './state/app.state';
describe('AppComponent', () => {
let store: MockStore<AppState>;
const initialState = mockInitialState;
let spectator: Spectator<AppComponent>;
const createComponent = createComponentFactory({
component: AppComponent,
declarations: [
AppComponent,
...
],
imports: [...],
providers: [ provideMockStore({ initialState })],
});
beforeEach(() => {
spectator = createComponent();
store = spectator.inject(MockStore);
});
it('should create', () => {
expect(spectator.component).toBeTruthy();
});
it('check state', () => {
const isLoggedIn = {
isLoggedIn: {
login: true
},
};
const state = {
...initialState,
...isLoggedIn,
};
store.setState(state);
spectator.fixture.detectChanges();
expect(spectator.component.isLoggedIn).toBe(true);
});
});
Вы можете использовать удобную функцию mockProvider.
В массиве провайдеров:
import { createComponentFactory, mockProvider, Spectator, SpyObject } from '@ngneat/spectator/jest';
import { Store } from '@ngrx/store';
providers: [mockProvider(Store)],