angular - 商店中的角度测试流
问题描述
我有 2 项服务AuthenticationStore
,NavigationStore
它们具有user$
和links$
流作为links
依赖于的属性user$
;user$
可以通过login()
的logout()
方法进行调整AuthenticationStore
。
服务按预期工作,我对它们进行单元测试并设定期望有问题。我的测试代码如下所示:
describe('NavigationStore', () => {
const AuthenticationStoreService = { user$: new BehaviorSubject<User>(null) };
let NavigationStoreService: NavigationStore;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
NavigationStore,
{
provide: AuthenticationStore,
useValue: AuthenticationStoreService
}
]
})
.compileComponents();
NavigationStoreService = TestBed.get(NavigationStore);
});
it('should have Logout Admin user', async(() => {
AuthenticationStoreService.user$.next({
id: '',
email: '',
group: 'A',
})
NavigationStoreService.links$.subscribe(
(links) => {
expect(links).toEqual([
{
title: 'Logout',
path: '/logout',
acl: 'A'
}
]);
}
);
}));
it('should have Login Guest user', async(() => {
AuthenticationStoreService.user$.next({
id: '',
email: '',
group: '0',
})
NavigationStoreService.links$.subscribe(
(links) => {
expect(links).toEqual([
{
title: 'Login',
path: '/login',
acl: '0'
}
]);
}
);
}));
});
我混合了“Spec ...没有期望”。或者第二个测试有管理员用户的结果(比如有前一个测试的值)。
服务代码:
导航商店:
const links: Navigation[] = [
{ title: 'Login', path: '/login', acl: '0' },
{ title: 'Logout', path: '/logout', acl: 'A' },
];
@Injectable({
providedIn: 'root',
})
export class NavigationStore {
private subject = new BehaviorSubject<Navigation[]>(null);
links$: Observable<Navigation[]> = this.subject.asObservable();
constructor(private auth: AuthenticationStore) {
this.links$ = this.auth.user$.pipe(
map((user) => links.filter((link) => link.acl.includes(user ? user.group : '0')))
);
}
}
身份验证存储:
const noUser = {
id: '',
email: '',
group: '0'
};
@Injectable({
providedIn: 'root',
})
export class AuthenticationStore {
private subject = new BehaviorSubject<User>(null);
user$: Observable<User> = this.subject.asObservable();
constructor(private http: HttpClient) {
const userProfile = localStorage.getItem(USER_DATA);
if (userProfile) {
this.subject.next(JSON.parse(userProfile));
} else {
this.subject.next(noUser);
}
}
login(email: string, password: string): Observable<User> {
return this.http.post<User>(URL + '/users/login', { email, password })
.pipe(
tap(user => {
localStorage.setItem(USER_DATA, JSON.stringify(user));
this.subject.next(user);
}),
catchError(() => {
this.logout();
return throwError('');
}),
shareReplay()
);
}
logout() {
localStorage.removeItem(USER_DATA);
this.subject.next(noUser);
}
}
我究竟做错了什么?
解决方案
您应该尝试像这样移动第一个AuthenticationStoreService
内部的初始化beforeEach
-
describe('NavigationStore', () => {
let AuthenticationStoreService;
let NavigationStoreService: NavigationStore;
beforeEach(() => {
AuthenticationStoreService = { user$: new BehaviorSubject<any>(null) };
TestBed.configureTestingModule({
providers: [
NavigationStore,
{
provide: AuthenticationStore,
useValue: AuthenticationStoreService
}
]
})
.compileComponents();
NavigationStoreService = TestBed.get(NavigationStore);
});
如上所述修改代码后,我看到您的所有测试都通过了。你也可以试试看它是否有效?
推荐阅读
- windows - 如何在容器中使用 gMSA 凭据来运行 FitNesse 测试?
- django - 更改列表中的模态表单 Django
- java - 从库存中仅移除 1 个项目
- sql-server - FullCalendar 不与服务器绑定
- flutter - 更新嵌套 ListView.builder 时滚动父 ListView
- node.js - 如何在我的基于 node.js mongodb 的应用程序中删除引用的集合 ID?
- python-3.x - 设置 django 进行部署
- python - 在 Python3 Flask Jinja2 模板中使用来自用户输入的参数调用函数
- powerbi - 使用条件筛选的 Power BI 度量
- python - flask-sqlalchemy:如何管理 SQL 视图?