简体   繁体   English

Jasmine 中的单元测试:监视服务功能并调用另一个服务功能

[英]Unit Testing in Jasmine: Spy on service function and call another service function

Below is my component function I want to write unit tests.下面是我要编写单元测试的组件函数。 I want to write a unit test to test the tokenRefresh function in auth service is being called when getItem returns a string to the component.我想编写一个单元测试来测试当 getItem 向组件返回字符串时调用身份验证服务中的tokenRefresh函数。

Component.ts组件.ts

refreshTokens(): void {
    const refreshToken = this.localStorageService.getItem('refresh_token');
    if (refreshToken) {
      this.authService.tokenRefresh(refreshToken).subscribe({
        next: (data: TokenModel) =>
          this.authService.routeToDashboard(
            data.access_token,
            data.refresh_token,
            data.expires_at
          ),
      });
    } else {
      this.notificationService.openSnackBar('Please login again.');
    }
  }

localStorage.service.ts localStorage.service.ts

@Injectable({
  providedIn: 'root'
})
export class LocalStorageService {

  constructor() { }

  getItem(key: string): string | null {
    return localStorage.getItem(key);
  }
}

I have created mick services in my component.spec.ts to mock LocalStorageService and AuthService as below.我在 component.spec.ts 中创建了 mick 服务来模拟 LocalStorageService 和 AuthService,如下所示。

export class LocalStorageStub {
  getItem(key: string): string | null {
    return '7677673437437';
  }
}

export class AuthorizeServiceStub {
  tokenRefresh(key: string) {
    return of({});
  }
  setItem(): void {

  }
}

Below is my complete component.spec.ts.下面是我完整的 component.spec.ts。

describe('LoginComponent', () => {
  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;
  let el: HTMLElement;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ LoginComponent ],
      imports: [
        HttpClientModule,
        RouterTestingModule,
        MatSnackBarModule,
        BrowserAnimationsModule
      ],
      providers:[
        { provide: LocalStorageService, useClass: LocalStorageStub },
        { provide: AuthorizeService, useClass: AuthorizeServiceStub}
      ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
  });

  it('should call token refresh if localstorage has refreshtoken', function() {
    component.refreshTokens();
    let service = fixture.debugElement.injector.get(LocalStorageService);
    let authService = fixture.debugElement.injector.get(AuthorizeService);
    service.getItem('key');
    const setPageSpy2 = spyOn(authService, 'tokenRefresh');
    expect(setPageSpy2).toHaveBeenCalled();
  });
});

I get the below result for my test case.我的测试用例得到以下结果。

在此处输入图像描述

Appreciate if someone can tell me what's the issue here.感谢有人能告诉我这里有什么问题。

Edit: The new order of unit test case编辑:单元测试用例的新顺序

it('should call token refresh if localstorage has refreshtoken', function() {
    let service = fixture.debugElement.injector.get(LocalStorageService);
    let authService = fixture.debugElement.injector.get(AuthorizeService);
    service.getItem('key');
    component.refreshTokens();
    const setPageSpy2 = spyOn(authService, 'tokenRefresh');
    expect(setPageSpy2).toHaveBeenCalled();
  });

I did not find the problem, but I found a workaround :D我没有发现问题,但我找到了解决方法:D

describe('LoginComponent', () => {
  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;
  const authorizeServiceStub: AuthorizeService = jasmine.createSpyObj(
    AuthorizeService,
    { 'tokenRefresh': of({}) },
  );

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ LoginComponent ],
      imports: [
        HttpClientModule,
        RouterTestingModule,
        MatSnackBarModule,
        BrowserAnimationsModule
      ],
      providers:[
        { provide: LocalStorageService, useClass: LocalStorageStub },
        { provide: AuthorizeService, useValue: authorizeServiceStub },
      ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
  });

  it('should call token refresh if localstorage has refreshtoken', function() {
    let service = fixture.debugElement.injector.get(LocalStorageService);
    service.getItem('key');
    component.refreshTokens();
    expect(authorizeServiceStub.tokenRefresh).toHaveBeenCalled();
  });
});

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

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