我有一个服务,它使用json-server作为我的数据库。我可以确认我的服务工作,因为我可以在一个组件中返回我的响应。但是我在尝试让Jasmin单元测试工作时遇到了这样的问题。
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);
});
});
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文档来的?我如何设置我的服务测试来测试返回数据,并与收据数据进行匹配?
当我改用subscribe函数而不是toPromise()时,我得到了。
Uncaught TypeError: 无法读取未定义的抛出的属性 "金额"。
似乎你正在从mock中刷新一个对象。HttpClient
而不是一个数组。
你应该做的是简单地改变
req.flush(receipt);
到
req.flush([receipt]);
你掉进的陷阱是服务的返回类型。一定要注意,类型只是为了开发目的而存在,在运行时并不存在。将你的返回类型标记为 Observable<Receipt[]>
并不保证您会得到 Observable
的 Receipt[]
当你运行代码时。我假设你的代码运行得很完美,因为你的后台返回一个数组的 Receipt
. 在测试中,它的工作原理不一样,因为你刷新的是一个简单的对象,而不是一个数组。在测试过程中。req.flush
成为你的后端服务。所以无论你在 req.flush
你的服务会回报给你,即使它是完全不同的东西比 Receipt[]