【问题标题】:Angular - unit test for a subscribe function in a componentAngular - 组件中订阅功能的单元测试
【发布时间】:2018-02-01 01:22:58
【问题描述】:

用于订阅的 Angular 4 单元测试。

我想测试我的订阅是否返回一个用户数组。 我想模拟一个用户列表并测试一个名为 getUsers 的函数。

订阅单元测试不起作用。 语法有问题。

这是我的用户界面:

export interface User {
  id: number;
  name: string;
  username: string;
  email: string;
  address: {
    street: string;
    suite: string;
    city: string;
    zipcode: string;
    geo: {
      lat: string;
      lng: string;
    }
  };
  phone: string;
  website: string;
  company: {
    name: string;
    catchPhrase: string;
    bs: string;
  };
};

这是我要测试的组件:

import { Component, OnInit } from "@angular/core";
import { Observable } from "rxjs/Observable";

import { UserService } from "../../services/user.service";
import { User } from "../../models/user.model";

@Component({
  selector: "home-users",
  templateUrl: "./home.component.html"
})

export class HomeComponent implements OnInit {
  private listOfUsers: User[];

  constructor(private userService: UserService) {
  }

  ngOnInit() {
    this.getUsers();
  }

  getUsers(): void {
    this.userService.getUsers().subscribe(users => {
      this.listOfUsers = users;
    });
  }
}

这是我的单元测试尝试:

import { TestBed, async, inject } from "@angular/core/testing";
import { HttpModule } from "@angular/http";

import { HomeComponent } from "./home.component";
import { UserService } from "../../services/user.service";
import { User } from "../../models/user.model";

describe("HomeComponent", () => {
  let userService;
  let homeComponent;
  let fixture;
  let element;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        HomeComponent
      ],
      providers: [
        UserService
      ],
      imports: [HttpModule]
    }).compileComponents();
  }));

  beforeEach(inject([UserService], s => {
    userService = s;
    fixture = TestBed.createComponent(HomeComponent);
    homeComponent = fixture.componentInstance;
    element = fixture.nativeElement;
  }));

  it("should call getUsers and return list of users", async(() => {
    // Arrange
    let response: User[] = [];

    // Act
    homeComponent.getUsers();

    fixture.detectChanges();
    fixture.whenStable().subscribe(() => {
        expect(homeComponent.listOfUsers).toEqual(response);
    });
  }));
});

【问题讨论】:

  • @Carsten 测试不起作用。测试的订阅部分的语法似乎有问题

标签: angular unit-testing jasmine karma-jasmine


【解决方案1】:

rxjs@6 及更高版本需要此功能。对于较旧的rxjs 版本答案如下:

    import { of } from 'rxjs';

    it("should call getUsers and return list of users", async(() => {
      const response: User[] = [];

      spyOn(userService, 'getUsers').and.returnValue(of(response))

      homeComponent.getUsers();

      fixture.detectChanges();
    
      expect(homeComponent.listOfUsers).toEqual(response);
    }));

对于旧的 rxjs 版本更改导入自:

    import { of } from 'rxjs';

    import { of } from 'rxjs/observable/of';

【讨论】:

  • 实际上我现在不能尝试 :D 这行得通吗?我添加了开玩笑的支持,昨天一切正常。但是现在我遇到了一些奇怪的错误:)
  • 这成功了!你认为这是一个值得的测试吗?还是应该只测试我的服务而不是组件?
  • 如果你有一些逻辑,我认为你需要测试。例如,您从服务器接收到一些数据,并且您让服务器处理这些数据。这是关键逻辑,绝不能被打破。你必须对此进行单元测试。在你的例子中:如果它很容易测试,为什么不呢。这将保护未来的开发者不会意外删除此订阅。
  • 有人在 spyOn 行的 of(response) 处有错误吗?我的是 User[] 不能分配给 void .. 由于没有返回值,如何解决它?
  • 用户界面/类中getUsers方法的返回类型是什么?
【解决方案2】:

我遇到了类似的问题,为了让它工作,我在 it

中使用了任意函数​​(在以下代码中,它被命名为 done

  it("should call getUsers and return list of users", async((done) => {
    // Arrange
    let response: User[] = [];

    // Act
    homeComponent.getUsers();

    fixture.detectChanges();
    fixture.whenStable().subscribe(() => {
        expect(homeComponent.listOfUsers).toEqual(response);
        done();
    });
  }));

【讨论】:

  • :) 谢谢,对我来说,而不是“订阅”,“然后”工作得很好,变化不大:-fixture.whenStable().then((response) => { expect(homeComponent.listOfUsers) .toEqual(response); done(); });
【解决方案3】:

在您的情况下,您也可以使用 fakeAsync 使用 tick() 来检测变化。 您还可以添加时间来勾选以指示如何记录等待。例如勾选(1000)

代码由 Sharikov Vladislav 修改

import { fakeAsync, getTestBed, TestBed, tick } from '@angular/core/testing';

it("should call getUsers and return list of users", fakeAsync(() => {
  const response: User[] = [];
  spyOn(userService, 'getUsers').and.returnValue(of(response))
  homeComponent.getUsers();
  tick();
  expect(homeComponent.listOfUsers).toEqual(response);
}));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2021-06-28
    • 2018-10-03
    • 1970-01-01
    • 2020-09-23
    相关资源
    最近更新 更多