加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angular – 如何在组件中模拟ngrx选择器

发布时间:2020-12-17 07:09:46 所属栏目:安全 来源:网络整理
导读:在组件中,我们使用ngrx选择器来检索状态的不同部分. public isListLoading$= this.store.select(fromStore.getLoading);public users$= this.store.select(fromStore.getUsers); fromStore.method是使用ngrx createSelector方法创建的.例如: export const g
在组件中,我们使用ngrx选择器来检索状态的不同部分.

public isListLoading$= this.store.select(fromStore.getLoading);
public users$= this.store.select(fromStore.getUsers);

fromStore.method是使用ngrx createSelector方法创建的.例如:

export const getState = createFeatureSelector<UsersState>('users');
export const getLoading = createSelector(
  getState,(state: UsersState) => state.loading
);

我在模板中使用这些observable:

<div class="loader" *ngIf="isLoading$| async"></div>
<ul class="userList">
    <li class="userItem" *ngFor="let user of $users | async">{{user.name}}</li>
</div>

我想写一个测试,我可以做以下事情:

store.select.and.returnValue(someSubject)

能够更改主题值并再次测试组件的模板这些值.

事实上,我们很难找到一种合适的方法来测试它.如何编写我的“andReturn”方法,因为select方法在我的组件中被调用两次,有两个不同的方法(MemoizedSelector)作为参数?

我们不想使用真正的选择器,所以模拟一个状态,然后使用真正的选择器似乎不是一个合适的单元测试方式(测试不会被隔离,并将使用真实的方法来测试组件行为).

解决方法

我遇到了同样的挑战并通过将我的选择器包装在服务中而一劳永逸地解决了这个问题,因此我的组件只使用该服务来获取数据而不是直接通过商店.我发现这清理了我的代码,使我的测试实现不可知,并使模拟更容易:

mockUserService = {
  get users$() { return of(mockUsers); },get otherUserRelatedData$() { return of(otherMockData); }
}

TestBed.configureTestingModule({
  providers: [{ provide: UserService,useValue: mockUserService }]
});

然而,在我这样做之前,我必须在你的问题中解决这个问题.

您的解决方案取决于您保存数据的位置.如果你在构造函数中保存它,如:

constructor(private store: Store) {
  this.users$= store.select(getUsers);
}

然后,每次要更改商店返回的值时,都需要重新创建测试组件.为此,请按以下方式创建一个函数:

const createComponent = (): MyComponent => {
  fixture = TestBed.createComponent(MyComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
  return component;
};

然后在更改商店间谍返回的值后调用它:

describe('test',() => {
  it('should get users from the store',() => {
    const users: User[] = [{username: 'BlackHoleGalaxy'}]; 
    store.select.and.returnValue(of(users));
    const cmp = createComponent();
    // proceed with assertions
  });
});

或者,如果要在ngOnInit中设置值:

constructor(private store: Store) {}
ngOnInit() {
  this.users$= this.store.select(getUsers);
}

事情变得容易一些,因为你可以创建一次组件,每次想要更改商店的返回值时只需调用ngOnInit:

describe('test',() => {
    const users: User[] = [{username: 'BlackHoleGalaxy'}]; 
    store.select.and.returnValue(of(users));
    component.ngOnInit();
    // proceed with assertions
  });
});

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读