Bla*_*axy 12 jasmine ngrx angular
在组件中,我们使用ngrx选择器来检索状态的不同部分.
public isListLoading$ = this.store.select(fromStore.getLoading);
public users$ = this.store.select(fromStore.getUsers);
Run Code Online (Sandbox Code Playgroud)
的fromStore.method
是使用NGRX创建createSelector
方法.例如:
export const getState = createFeatureSelector<UsersState>('users');
export const getLoading = createSelector(
getState,
(state: UsersState) => state.loading
);
Run Code Online (Sandbox Code Playgroud)
我在模板中使用这些observable:
<div class="loader" *ngIf="isLoading$ | async"></div>
<ul class="userList">
<li class="userItem" *ngFor="let user of $users | async">{{user.name}}</li>
</div>
Run Code Online (Sandbox Code Playgroud)
我想写一个测试,我可以做以下事情:
store.select.and.returnValue(someSubject)
Run Code Online (Sandbox Code Playgroud)
能够更改主题值并再次测试组件的模板这些值.
事实上,我们很难找到一种合适的方法来测试它.如何编写我的"andReturn"方法,因为该select
方法在我的组件中被调用两次,有两个不同的方法(MemoizedSelector)作为参数?
我们不想使用真正的选择器,所以模拟一个状态,然后使用真正的选择器似乎不是一个合适的单元测试方式(测试不会被隔离,并将使用真实的方法来测试组件行为).
我遇到了同样的挑战,并通过将选择器包装在服务中而一劳永逸地解决了问题,因此我的组件只是使用服务来获取其数据,而不是直接通过存储。我发现这清理了我的代码,使我的测试与实现无关,并使模拟更加容易:
mockUserService = {
get users$() { return of(mockUsers); },
get otherUserRelatedData$() { return of(otherMockData); }
}
TestBed.configureTestingModule({
providers: [{ provide: UserService, useValue: mockUserService }]
});
Run Code Online (Sandbox Code Playgroud)
但是,在执行此操作之前,我必须先解决您的问题。
解决方案将取决于您将数据保存在何处。如果以constructor
类似方式保存它:
constructor(private store: Store) {
this.users$ = store.select(getUsers);
}
Run Code Online (Sandbox Code Playgroud)
然后,您每次需要更改返回的值时,都需要重新创建测试组件store
。为此,请按照以下方式创建函数:
const createComponent = (): MyComponent => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
return component;
};
Run Code Online (Sandbox Code Playgroud)
然后在更改商店间谍返回的值之后调用:
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
});
});
Run Code Online (Sandbox Code Playgroud)
或者,如果要在中设置值ngOnInit
:
constructor(private store: Store) {}
ngOnInit() {
this.users$ = this.store.select(getUsers);
}
Run Code Online (Sandbox Code Playgroud)
事情要容易一些,因为您只需创建一次组件,然后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
});
});
Run Code Online (Sandbox Code Playgroud)
如果您要测试选择器本身,则将选择器移至服务中并不会消除模拟选择器的需要。ngrx 现在有自己的模拟方式,如下所述: https ://ngrx.io/guide/store/testing
归档时间: |
|
查看次数: |
5660 次 |
最近记录: |