angular - Angular 服务测试未通过
问题描述
我有一个使用 json-server 作为我的数据库的服务。我可以确认我的服务可以正常工作,因为我可以在组件中返回我的响应。但是我在尝试让 Jasmin 单元测试正常工作时遇到了这样的问题。
这是我的收据-数据-public.spec.ts 文件
import { ReceiptsDataPublic } from './receipts-data-public';
import { TestBed, fakeAsync, inject } from '@angular/core/testing';
import {
HttpClientTestingModule,
HttpTestingController,
} from '@angular/common/http/testing';
import { Receipt } from '../classes/receipt';
import { HttpClient } from '@angular/common/http';
describe('ReceiptsDataPublic', () => {
let httpTestingController: HttpTestingController;
let service: ReceiptsDataPublic;
let httpClient: HttpClient;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ReceiptsDataPublic],
imports: [HttpClientTestingModule],
});
// We inject our service (which imports the HttpClient) and the Test Controller
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
service = TestBed.get(ReceiptsDataPublic);
});
beforeEach(() => {
service = TestBed.get(ReceiptsDataPublic);
});
afterEach(() => {
httpTestingController.verify();
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should call getDevReceipts', () => {
const serviceSpy = spyOn(service as ReceiptsDataPublic, 'getDevReceipts');
service.getDevReceipts();
expect(serviceSpy.calls.count()).toBe(1);
});
it('should call getReceipts', () => {
const serviceSpy = spyOn(service as ReceiptsDataPublic, 'getReceipts');
service.getReceipts();
expect(serviceSpy.calls.count()).toBe(1);
});
it('returned Observable should match the right data', (done: DoneFn) => {
const receipt = {
id: 1,
expenseDate: "2019-04-26T15:15:56.948Z",
description: "Id cupiditate sint et dolores molestias consequuntur necessitatibus ipsa. Qui assumenda consequuntur enim cumque eos eligendi culpa sit aspernatur. Qui molestiae voluptate sed a mollitia voluptatem rerum. Neque accusamus voluptate iusto vero illo consequuntur. Et ut at quod tenetur veritatis recusandae quia sed. Perspiciatis ipsum consequuntur neque distinctio.",
amount: 122.00,
imgUrl:"https://source.unsplash.com/1600x900/?product"
};
service.getDevReceipts()
.subscribe(res => {
expect(res[0].amount).toEqual(12.9);
done();
});
const req = httpTestingController.expectOne('http://localhost:3000/receipts');
expect(req.request.method).toEqual('GET');
req.flush(receipt);
});
});
这是我的实际收据-数据-public.service.ts
import { Injectable } from '@angular/core';
import { ReceiptsDataService } from './receipts-data.service';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Receipt } from '../classes/receipt';
import { throwError, Observable } from 'rxjs';
@Injectable()
export class ReceiptsDataPublic implements ReceiptsDataService {
private LOCAL_REST_API_SERVER = 'http://localhost:3000/receipts';
constructor(private httpClient: HttpClient) {}
handleError(error: HttpErrorResponse) {
let errorMessage = 'Unknown error!';
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
errorMessage = `Error: ${error.error.message}`;
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
return throwError('Something bad happened; please try again later.');
}
getDevReceipts(): Observable<Receipt[]> {
return this.httpClient.get<Receipt[]>(this.LOCAL_REST_API_SERVER);
}
getReceipts(): Observable<Receipt[]> {
throw new Error('Method not implemented.');
}
}
但我不断得到以下信息:
我不明白我在遵循 Angular 文档时做错了什么?如何设置我的服务测试以测试返回数据并将其与收据数据匹配?
当我更改为订阅函数而不是 toPromise() 时,我得到:
未捕获的类型错误:无法读取未定义抛出的属性“数量”
解决方案
似乎您正在从模拟HttpClient
而不是数组中刷新对象。
你应该做的只是改变
req.flush(receipt);
至
req.flush([receipt]);
您陷入的陷阱是服务的返回类型。请始终注意,类型仅用于开发目的,并且在运行时不存在。将您的返回类型标记为Observable<Receipt[]>
并不能保证您在运行代码时会得到一个Observable
。Receipt[]
我假设您的代码运行完美,因为您的后端返回一个Receipt
. 它在测试中的工作方式不同,因为您刷新了一个简单的对象而不是数组。在测试期间,req.flush
成为您的后端服务。所以无论你输入什么req.flush
,你的服务都会返回,即使它完全不是Receipt[]
推荐阅读
- azure - Azure OAuth:无法在管理员同意的情况下以编程方式创建应用以获得权限
- c# - 从不同类型的列表中搜索名称
- yii2 - Yii2模型规则黑名单词数组检查
- swift - 从 RealityKit 中的场景中删除实体
- javascript - Google Apps 脚本 - 想要截断表单中特定列中的文本
- r - 如何解释此错误以及如何处理?NA 和重新编码的问题
- c# - .NET Core 3.1 与 PostreSQL jsonb JsonDocument 映射无法正常工作,因为“无法翻译 LINQ 表达式”
- javascript - 获取未定义的 Javascript
- python - 使用 selenium Chrome 驱动程序清除 Chrome 浏览器中的缓存
- mysql - 无法对 MySQL 数据库添加约束