3

我正在尝试与 Angular、Jest 和 Spectator 一起编写单元测试。现在我正在努力嘲笑 NgRx 商店。MockStore在尝试获取从 Spectator 实例提供的 NgRx 实例时,我收到“No provider for MockStore”错误。

我已经阅读了有关模拟和单元测试的 NgRx 文档,并且通过阅读文档,我可以在不使用 Spectator 的情况下模拟 NgRx 存储,我尝试在谷歌上搜索寻求帮助,但似乎找不到一起模拟 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获取实例,我就会收到“No provider for MockStore”-错误。我也尝试过提供这样的:spectator.injectspectator.getMockStore

    const createComponent = createComponentFactory({
        component: MyComponent,
        componentProviders: [
            mockProvider(MockStore, provideMockStore()),
        ],
        shallow: true,
        detectChanges: false,
    });

但是显然,我收到错误“没有商店提供者”。

也许这里有人可以帮助我?提前致谢!

4

2 回答 2

0

您可以使用方便的 mockProvider功能。

在提供者数组中:

import { createComponentFactory, mockProvider, Spectator, SpyObject } from '@ngneat/spectator/jest';
import { Store } from '@ngrx/store';

providers: [mockProvider(Store)],
于 2020-04-12T22:20:24.863 回答
0

I had the same issue, this seems to be working for me:

In setup-jest.ts I've defined global injections with common test imports and provider for store using provideMockStore with initial state:

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 })],
});

Then when testing it in components I'm using MockStore and spies:

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})
  });
});

Honestly, I've no idea if this is the best way but it works. If you see some way to improve this I'll be glad to hear it.

于 2020-05-11T08:59:00.997 回答