【问题标题】:Angular testing streams in store商店中的角度测试流
【发布时间】:2020-09-21 14:27:36
【问题描述】:

我有 2 个服务 AuthenticationStoreNavigationStore 具有 user$links$ 流作为属性,其中 links 依赖于 user$user$ 可以通过logout()login()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')))
    );
  }
}

AuthenticationStore

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

我做错了什么?

【问题讨论】:

    标签: angular unit-testing rxjs observable


    【解决方案1】:

    您应该尝试像这样将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);
      });
    

    如前所述修改代码后,我看到您的所有测试都通过了。能不能也试试看行不行?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-18
      • 2020-05-14
      • 2015-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 2015-06-27
      相关资源
      最近更新 更多