我在为间接调用多个HTTP请求的函数编写单元测试时遇到问题。
正在测试的服务具有以下结构:
/* content.service.ts */
import { Injectable } from "@angular/core"
import { ApiService } from "services/api/api.service"
@Injectable()
export class ContentService {
public languages: Array<any>
public categories: Array<any>
constructor(private apiService: ApiService) {}
public async fetchLanguages(): Promise<boolean> {
const data: any = await this.apiService.getData("language")
if (!data) return false
this.languages = data
return true
}
public async fetchCategories(): Promise<boolean> {
const data: any = await this.apiService.getData("category")
if (!data) return false
this.categories = data
return true
}
public async initService(): Promise<boolean> {
const statusLanguages: boolean = await this.fetchLanguages()
if (!statusLanguages) return false
const statusCategories: boolean = await this.fetchCategories()
if (!statusCategories) return false
return true
}
}
服务测试文件如下所示:
/* content.service.spec.ts */
import {
HttpClientTestingModule,
HttpTestingController
} from "@angular/common/http/testing"
import { TestBed } from "@angular/core/testing"
import { ApiService } from "services/api/api.service"
import { ContentService } from "./content.service"
describe("ContentService:", () => {
let contentService: ContentService
let httpMock: HttpTestingController
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ HttpClientTestingModule ],
providers: [ ApiService, ContentService ]
})
contentService = TestBed.get(ContentService)
httpMock = TestBed.get(HttpTestingController)
})
afterEach(() => {
httpMock.verify()
})
/* Dummy data */
const languages = [
{ id: 1, uid: "en", active: true },
{ id: 2, uid: "es", active: false },
{ id: 3, uid: "hr", active: false }
]
const categories = [
{ id: 1, uid: "default" },
{ id: 2, uid: "alternative" }
]
describe("initService:", () => {
it("successful response", (done: DoneFn) => {
contentService.initService().then(result => {
expect(result).toEqual(true)
expect(contentService.languages).toEqual(languages)
expect(contentService.categories).toEqual(categories)
done()
})
const requests = httpMock.match(req => !!req.url.match(/api\/data/))
expect(requests.length).toBe(2)
requests[0].flush({ status: "ok", data: languages })
requests[1].flush({ status: "ok", data: categories })
})
})
})
当使用ng test
运行单元测试时,会抛出以下错误:
TypeError: Cannot read property 'flush' of undefined
TypeError与该行相关:
requests[1].flush({ status: "ok", data: categories })
这使我得出结论,第一个请求被正确处理,而第二个请求没有。
HttpTestingController中的方法match
是否应该捕获与提供的正则表达式匹配的所有HTTP请求?
答案 0 :(得分:0)
编写单元测试时,您应该只测试一个单元。在这种情况下,您的单位为ContentService
。请记住,您不必测试它的依赖项。我看到ApiService
是您服务中的依赖,用于发出 Http请求。所以你没有测试你是否正在发出http请求。您只需使用模拟值或茉莉花间谍对象来模拟ApiService。
const spy = jasmine.createSpyObj('ApiService', ['getData']);
TestBed.configureTestingModule({
providers: [
ContentService,
{ provide: ApiService, useValue: spy }
]
});
您需要在此测试的是ContentService
内的变量根据输入值获取正确的值和方法的返回值。
您可以单独测试ApiService
。在进行单元测试时,不要尝试测试类的依赖关系。