Angular - 组件中订阅功能的单元测试
Posted
技术标签:
【中文标题】Angular - 组件中订阅功能的单元测试【英文标题】:Angular - unit test for a subscribe function in a component 【发布时间】: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 测试不起作用。测试的订阅部分的语法似乎有问题 【参考方案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);
));
【讨论】:
以上是关于Angular - 组件中订阅功能的单元测试的主要内容,如果未能解决你的问题,请参考以下文章
单元测试 queryParams 订阅 (Angular5)
Angular 4 单元测试中未调用 ngOnChanges detectChanges()