【问题标题】:NgRx 8 Test provideMockStore - setState for State SliceNgRx 8 测试 provideMockStore - 状态切片的 setState
【发布时间】:2019-12-08 18:43:12
【问题描述】:

我的 NgRx 实现有一个智能组件测试,看起来像这样:

describe( 'Component', () => {
  let store: MockStore<State>;

  beforeEach( async( () => {
    TestBed.configureTestingModule( {
        /* ... */
        providers: [
            provideMockStore( { initialState: fromReducer.initialState } )
        ]
    } ).compileComponents();
    store = TestBed.get<Store<State>>( Store );
  } ) );

  it( 'should load items in #ngOnInit', () => {
    store.setState( {
        item: {
          ...fromReducer.initialState,
          entities: { [item.id]: item },
        },
        otherFeature: null,
        otherFeature: null,
        otherFeature: null
    } );
    component.items$.subscribe( items =>
        store.select( ItemStoreSelectors.selectItems ).subscribe( fromStore => expect( items ).toEqual( fromStore ) )
    );
  } );
});

我使用 provideMockStoresetState 来模拟我的 NgRx 状态。这种方式一切正常,但我真的不喜欢这部分:

store.setState( {
    item: {
      ...fromReducer.initialState,
      entities: { [item.id]: item },
    },
    otherFeature: null,
    otherFeature: null,
    otherFeature: null
} );

我必须将我的状态的所有其他功能切片添加到 setState 函数。否则 Typescript 会抛出错误。


所以最好我不想设置根状态,而是像这样设置一个特定的特征片:

store.setState( {
  ...fromReducer.initialState,
  entities: { [item.id]: item },
} );

我找不到任何有关如何将 provideMockStore 用于状态 here 的特定切片的文档。

【问题讨论】:

    标签: angular typescript ngrx ngrx-store angular-test


    【解决方案1】:

    正如 xander 所说,您可以使用 mockSelectors。 TS 抱怨的原因是你的打字方式。

    MockStore&lt;State&gt; 可能是你的整个状态树,对于一个特征切片,使用MockStore&lt;FeatureState&gt;

    【讨论】:

    • 我实际上已经尝试设置MockStore&lt;FeatureState&gt;,但也没有成功
    • 我的意思是TS没有抱怨,但是运行测试时出现错误
    【解决方案2】:

    我建议在这里采取不同的方法。你应该做的是独立地对你的选择器和组件进行单元测试。

    NgRx 8 允许mock selectors。在您的组件中使用它来验证组件的逻辑是否正确。

    然后,独立地对您的选择器进行单元测试,以验证您的选择器是否按预期工作。

    这样测试是独立的,不脆弱的,真正的单元测试。

    编辑:我链接的文档是官方的,但是模拟选择器的另一种方法是:

      beforeEach(() => {
        TestBed.configureTestingModule({
          providers: [
            provideMockStore({
              selectors: [
                {
                  selector: yourSelectorNameHere,
                  value: someMockValueHere
                }
              ]
            })
          ]
        });
    
    

    【讨论】:

    • 我已经对 reducer、effects 和 selectors 进行了独立的单元测试。这实际上是针对智能组件的。所以我不需要测试智能组件?
    • 不,您当然应该测试该组件。但是,不要通过实际允许选择器运行来测试它。模拟它,并根据您模拟的预期行为测试组件中的逻辑。
    • 好吧,效果也一样?...因为我也在效果测试中使用了模拟商店
    • 是的,效果也一样。如果您允许您的选择器实际运行,并且您的选择器中存在错误,则对您的组件/效果的测试将失败。它不会因为它试图测试的代码中的错误而失败——它会因为你的选择器中的错误而失败!这就是你应该嘲笑它的原因。
    • 谢谢!...明天我会看看我的代码,看看我是否还有其他问题,然后检查你的答案:)
    猜你喜欢
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多