简体   繁体   English

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

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

I have a login page I need to test, which uses an authentication service.我有一个需要测试的登录页面,它使用身份验证服务。 Roughly speaking, when the login button is pressed, at some point this occurs :粗略地说,当按下登录按钮时,有时会发生这种情况:

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

(this is part of the code I am supposed to test and therefore I should ideally not modify it) (这是我应该测试的代码的一部分,因此我最好不要修改它)

Internally, $authentification is a Subject :在内部, $authentification 是一个 Subject :

$authentification = new Subject<any>();

which is attached to the service method authentification :附加到服务方法身份验证:

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

The service calls up the authentication API, stores the results in the local storage, and then feeds a confirmation in the Subject object, which will then be used by the login page to decide what to do next.该服务调用身份验证 API,将结果存储在本地存储中,然后在 Subject 对象中提供确认,然后登录页面将使用该确认来决定下一步做什么。

When testing the login page, what am I supposed to simulate here?在测试登录页面时,我应该在这里模拟什么? Should I mock the service, subject and local storage, or get the service from the component and then mock the subject and local storage?我应该模拟服务、主题和本地存储,还是从组件中获取服务然后模拟主题和本地存储? I'm not quite sure how to proceed here.我不太确定如何在这里进行。

Unit testing is about testing a unit of code.单元测试是关于测试一个代码单元。 Everything outside of this unit should be mocked .这个单元之外的一切都应该被嘲笑

So yes, you should mock your service.所以是的,你应该模拟你的服务。 From there, think about it : since you have mocked the service, why should you mock anything else in it ?从那里开始,想一想:既然你已经模拟了服务,为什么还要模拟其中的任何其他内容? A mock has no dependency, so just mock the service and nothing else.模拟没有依赖关系,因此只需模拟服务即可。

Here is the simplest mock you can make to test your code这是您可以用来测试代码的最简单的模拟


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

From there, simply inject this mock in your component从那里,只需将此模拟注入您的组件中


component = new MyComponent(serviceMock);

And now, make a meaningful test现在,做一个有意义的测试


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