Как смоделировать селекторы в модульных тестах nrgx 8? - PullRequest
0 голосов
/ 10 ноября 2019

Я учусь писать модульные тесты для приложения ngrx8, используя Jest.

Я тестирую компонент, имеющий подписку на селектор в ngOnInit:

ngOnInit(): void {
  this.store.pipe(select(someSelector(this.parameter))).subscribe((res: 
    // some logic here
  });
}

В .spec. Файл TS, который я поместил provideMockStore в конфигурации TestBed:

TestBed.configureTestingModule({
    // ...
    providers: [
      provideMockStore({
        initialState, // defined somewhere above
        selectors: [
          {
            selector: someSelector('param'),
            value: {a: 'b', c: 'd'}
          }
        ]
      })
    ]
    // ...
}).compileComponents();;

Так что я ожидаю, что во время выполнения этого модульного теста я должен ввести подписку (раздел "немного логики здесь") в компонентном файле .tsи res будет равно {a: 'b', c: 'd'}.

Этого не происходит, вместо этого игнорируется селекторный селектор и используется реальный.

То, что я пробовал:

  • store.overrideSelector(someSelector('param'), {a: 'b', c: 'd')

  • Ввод fixture.detectChanges(), await fixture.whenStable(), в разные места

Сейчас меня нетпараметров, а документация NGRX почти ничего не охватывает.

1 Ответ

2 голосов
/ 10 ноября 2019

Насмешка над селектором не кажется лучшим решением. Было бы лучше издеваться над самим магазином.

Вы можете указать состояние в:

provideMockStore({ initialState: your_state })

или

mockStore.setState(your_state);

mockStore.setState(...) позволяет проводить тестыс другим значением в вашем магазине внутри ваших тестов.

НО Я предлагаю вам сделать следующее, если у вас есть сложное хранилище:

  • создать класс, гдеу вас будет состояние ложного магазина: MockStoreState.

type RecursivePartial<T> = {
  [P in keyof T]?:
  T[P] extends (infer U)[] ? RecursivePartial<U>[] :
    T[P] extends object ? RecursivePartial<T[P]> :
      T[P];
};

export class MockStoreState {
  private store_a: RecursivePartial<Store_A>;
  private store_b: RecursivePartial<Store_b>;

  build(): any {
    const defaultStore_a = {
      ...
    };
    const defaultStore_b = {
      ...
    };

    return {
      store_a: { ...defaultStore_a , ...this.store_a},
      store_b: { ...defaultStore_b , ...this.store_b },
    };
  }

  setStore_a(value: RecursivePartial<Store_A>): Store_A_State {
    this.store_a= value;
    return this;
  }

  setStore_b(value: RecursivePartial<DatasourceState>): Store_B_State {
    this.store_b= value;
    return this;
  }
}
  • Установите состояние в вашем магазине в тесте:
describe(MyComponent.name, () => {
   ...
   let mockStore: MockStore<any>;

   beforeEach(() => {
       ...
       mockStore = TestBed.get(Store);
   })


   it('...', () => {
     const state = new MockStoreState().setStore_a({...})
    .build();

    mockStore.setState(state);

   // HERE you have set the data in your store.
   })
}
...