gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 17:03:19 28 4
gpt4 key购买 nike

在组件中,我们使用 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
);

我在模板中使用这些可观察值:

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

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

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

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

最佳答案

我遇到了同样的挑战,并通过将我的选择器包装在服务中一劳永逸地解决了它,所以我的组件只使用该服务来获取它们的数据,而不是直接通过商店。我发现这清理了我的代码,使我的测试与实现无关,并使模拟变得更加容易:

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

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

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

适合您的解决方案取决于您保存数据的位置。如果您将其保存在 constructor 中,例如:

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

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

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

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

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', () => {
it('should get users from the store', () => {
const users: User[] = [{username: 'BlackHoleGalaxy'}];
store.select.and.returnValue(of(users));
component.ngOnInit();
// proceed with assertions
});
});

关于angular - 如何在组件中模拟 ngrx 选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49288024/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com