【问题标题】:NgRX provideMockStore createSelector state undefinedNgRX provideMockStore createSelector 状态未定义
【发布时间】:2021-04-08 04:24:42
【问题描述】:

当使用提供的 mockStore 时,我的功能/选择器函数只会将状态视为未定义。

因此,我只能模拟选择器,因此无法执行更完全集成的测试。

当模拟商店提供状态时,选择器不应该看到状态还是应该这样做?

创建模拟商店

     TestBed.configureTestingModule({
        providers: [
            AuthGuardGuard,
            provideMockStore({
                initialState: { ...initialState },
            }),
        ],
    });

然后记录选择器应该看到的状态,这是未定义的。

export const currentUser = createSelector(
    authRootFeature,
    (state: fromAuthRoot.State) => {
        console.log(state); // Undefined
        return state.auth.currentUser;
    }
);

【问题讨论】:

    标签: angular ngrx angular-test


    【解决方案1】:

    MockStore 应该设置状态,我将与您分享两个可行的实现,您可以选择您喜欢的实现,您的问题中缺少信息,因此很难指出为什么这对您不起作用。

    这是一个:

    我的选择器:

    export const selectFeature = createFeatureSelector<State, FeatureState>('feature');
    
    export const getFeatureProperty = createSelector(
      selectFeature,
      (state) => state.featureProperty
    );

    我的测试文件:

    describe('MyComponent', () => {
      let component: MyComponent;
      let fixture: ComponentFixture<MyComponent>;
      let mockStore: MockStore<State>;
    
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          declarations: [LogsMenuViewComponent, LogsMenuViewDropdownComponent],
          providers: [provideMockStore({ initialState: { feature: { featureProperty: 123 } } as State })],
        }).compileComponents();
      }));
    
      beforeEach(() => {
        fixture = TestBed.createComponent(MyComponent);
        mockStore = TestBed.inject(Store) as MockStore<State>;
        component = fixture.componentInstance;
        fixture.detectChanges();
      });
    });

    之所以可行,是因为我的选择器使用了一个特性,选择器,所以它能够正确获取状态。

    另一个可能对您有用的实现是覆盖选择器,如下所示:

      describe('selectors', () => {
        let mockShowsSelector;
        beforeEach(() => {
          mockShowsSelector = store.overrideSelector(selectFavoriteShows, [{
            id: 3,
            name: 'C',
            description: 'Show C',
            imgUrl: '',
            isFavorite: true
          }]);
          fixture.detectChanges();
        });
    
        it('should render all favorite shows', () => {
          expect(fixture.debugElement.queryAll(By.css('.mat-card')).length).toBe(1);
        });
    
        it('should update the UI when the selector changes', () => {
          mockShowsSelector.setResult([ // overide selector
            {
              id: 1,
              name: 'A',
              description: 'Show A',
              imgUrl: '',
              isFavorite: true
            },
            {
              id: 2,
              name: 'B',
              description: 'Show B',
              imgUrl: '',
              isFavorite: true
            }
          ]);
          store.refreshState();
          fixture.detectChanges();
          expect(fixture.debugElement.queryAll(By.css('.mat-card')).length).toBe(2);
        });
      })

    【讨论】:

    • 谢谢你的例子。看来我的功能选择器有点不正确。进行了一些更改,并且能够让 mockStore 选择工作!
    • 我今天刚刚在做这个,所以很高兴看到你的问题 :) 如果你正在寻找测试 NgRx 的资源,我可以推荐这个视频:youtube.com/…
    • 再次感谢,非常感谢,视频非常棒。我在测试服务时没有使用 compileComponents() 。似乎不使用 compileComponents 会导致存储实例不完整。
    猜你喜欢
    • 2019-12-08
    • 2020-06-21
    • 2018-06-19
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多