繁体   English   中英

使用 Subject 和 localstorage 在 Jasmine 中测试 Angular 服务

[英]Testing an Angular service in Jasmine using Subject and localstorage

我有一个需要测试的登录页面,它使用身份验证服务。 粗略地说,当按下登录按钮时,有时会发生这种情况:

  this.userService.$authentification.subscribe((res)=>{
    if(res.success){
      this.router.navigate(['/dashboard']);
    }else{
      console.error(res.error.code)
      this.error=res.error;
    }
  })
  this.userService.authentification(login, pwd);

(这是我应该测试的代码的一部分,因此我最好不要修改它)

在内部, $authentification 是一个 Subject :

$authentification = new Subject<any>();

附加到服务方法身份验证:

  authentification(login : string, password : string){
    let body = {
      login: login,
      password: password
    }
    this.jwtLocalstorage.remove();
    let post = this.http.post<any>(environment.api + 'user/login/index.php', body, {}).subscribe(response => {
      post.unsubscribe();
      if(response.jwt){
        this.jwtLocalstorage.add(response.jwt, response.data.id);
        this.$authentification.next({
          success:true,
          error: null
        });
      }else{
        this.$authentification.next({
          success:false,
          error: {code:"0X"}
        });
      }
    },response => {
      post.unsubscribe();
      this.$authentification.next({
        success:false,
        error: response.error
      });
    });
  }

该服务调用身份验证 API,将结果存储在本地存储中,然后在 Subject 对象中提供确认,然后登录页面将使用该确认来决定下一步做什么。

在测试登录页面时,我应该在这里模拟什么? 我应该模拟服务、主题和本地存储,还是从组件中获取服务然后模拟主题和本地存储? 我不太确定如何在这里进行。

单元测试是关于测试一个代码单元。 这个单元之外的一切都应该被嘲笑

所以是的,你应该模拟你的服务。 从那里开始,想一想:既然你已经模拟了服务,为什么还要模拟其中的任何其他内容? 模拟没有依赖关系,因此只需模拟服务即可。

这是您可以用来测试代码的最简单的模拟


const state = new Subject<any>();
serviceMock: any = {
  $authentification: state.asObservable(),
  authentification: jasmine.createSpy()
};

从那里,只需将此模拟注入您的组件中


component = new MyComponent(serviceMock);

现在,做一个有意义的测试


it('Should redirect in case of success', (done) => {

  state.pipe(first()).subscribe(() => {
    expect(component.router.navigate)
      .toHaveBeenCalledOnceWith(['/dashboard']);
    done();
  });

  component.yourFunctionToCallToTest();

  state.next({ success: true });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM