首页 > 解决方案 > 在 ngOnInt 进行远程调用的单元测试

问题描述

这是我的组件:

 export class MyComponent implements OnInit {

    me: User;  
    let userServiceGetMeSpy; 

    constructor(private userService: UserService) {

    }

    ngOnInit() {


        this.userService.getMe().subscribe(user => {

          this.me = user;

在 ngOnit 的组件开始时,我正在调用一个服务来进行远程调用并获取用户对象,然后我将返回的对象设置为组件的“我”属性。

我的目标是编写一个单元测试,以检查在从 ngOnit 方法成功调用 UserService 的 getMe 方法后是否设置了 me 属性。

我可以考虑这个代码的规范:

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;
  let userService: UserService;
  let mockedUser = new User();

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    userService = TestBed.get(UserService);


    mockedUser.Name = "Admin User";

    userServiceGetMeSpy = spyOn(userService, "getMe").and.callFake(() => {
      return of<User>(mockedUser)
    })

    fixture.detectChanges();
  });

我对单元测试的编写感到困惑:

  it('should set "me" property on calling getMe at ngOnit on MyComponent', () => {

    //What to write here?

  });

我可以想到一个测试来检测是否调用了 getMe 方法

  it('should have called user service get me on page load', () => {

    component.ngOnInit();
    fixture.detectChanges();
    expect(userServiceGetMeSpy).toHaveBeenCalled();
  });

我需要进一步检查在该调用之后是否调用了“我”属性。

标签: angulartypescriptunit-testingkarma-jasmine

解决方案


首先,userServiceGetMeSpyMyComponent班级中删除。您唯一需要UserService.getMe的是在调用组件之前模拟服务ngOnInit调用。

spyOn(userService, 'getMe').and.returnValue(of(user));

请注意,这fixture.detectChanges会触发组件的更改检测周期并隐式调用其ngOnInit方法。因此,无需ngOnInit再次显式调用您的测试。

您可以按如下方式编写测试。

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;
  const user = new User();
  let userService: UserService;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ MyComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    userService = TestBed.get(UserService);
    spyOn(userService, 'getMe').and.returnValue(of(user));
    fixture.detectChanges();
  });

  it('should have called user service get me on page load', () => {
    expect(userService.getMe).toHaveBeenCalledTimes(1);
    expect(component.me).toBe(user);
  });
});

推荐阅读