Angular 在异步函数内部比较数据时,HttpClient 单元测试不会失败
Angular HttpClient unit tests won't fail when comparing data inside of an asynchronous function
我正在尝试对几个简单的 GET 请求进行单元测试,但无论我做什么,我都无法让测试失败。
如果我将 ('GET')
更改为 ('POST')
它将失败,但是所有 api 数据无论如何都会通过。
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { mockPhoneNumbers } from '../mocks/data/phoneNumbers.mock';
import { PhoneNumberApiService } from './phone-number-api.service';
describe('PhoneNumberApiService', () => {
let service: PhoneNumberApiService;
let httpTestingController: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [PhoneNumberApiService],
});
service = TestBed.get(PhoneNumberApiService);
httpTestingController = TestBed.get(HttpTestingController);
});
afterEach(() => {
// After every test, assert that there are no more pending requests.
httpTestingController.verify();
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should get the phone numbers successfully', () => {
service
.getPhoneNumbers()
.subscribe(phoneNumbers => {
expect(phoneNumbers).toEqual('bob');
expect(phoneNumbers[0].id).toEqual('b8bfea4d-a26f-9e4e-cbd4-39eb69cdaa58');
expect(phoneNumbers[1].friendlyName).toEqual('Dev Test');
});
const req = httpTestingController.expectOne('phoneNumbers');
expect(req.request.method).toEqual('GET');
req.flush(mockPhoneNumbers);
});
it('should get the phone number details successfully', () => {
const { id: phoneNumberId } = mockPhoneNumbers[0];
service
.getPhoneNumberDetails(phoneNumberId)
.subscribe(phoneNumber => expect(phoneNumber).toEqual(mockPhoneNumbers[0]));
const req = httpTestingController.expectOne(`phoneNumbers/${phoneNumberId}`);
expect(req.request.method).toEqual('GET');
req.flush('bob');
});
});
当然用模拟数据刷新请求然后期望模拟数据是 bob
是错误的。在底部测试中,使用 bob
刷新请求并期望数据等于数组中的第一个 phone 数字应该会失败。
关于你的测试的问题是你让你的 "it" 函数和预期异步没有明确告诉茉莉花.
您需要在其他地方使用 done 函数来告诉测试正在等待什么(查看 here 关于 jasmine 异步测试的好教程)
下面是一个基于您的代码的示例:
...
//Receive the done function like this
it('should get the phone numbers successfully', (done) => {
service
.getPhoneNumbers()
.subscribe(phoneNumbers => {
expect(phoneNumbers).toEqual('bob');
expect(phoneNumbers[0].id).toEqual('b8bfea4d-a26f-9e4e-cbd4-39eb69cdaa58');
expect(phoneNumbers[1].friendlyName).toEqual('Dev Test');
//Tell the test that only in here all the work was done
done();
});
const req = httpTestingController.expectOne('phoneNumbers');
expect(req.request.method).toEqual('GET');
req.flush(mockPhoneNumbers);
});
....
此外,为了回答 ,jest 是一个测试运行器,构建在 jasmine 框架之上(这意味着 jest 语法类似于 jasmin,但不相同)。但是对于这种情况,我想使用 done 可以解决你的问题。
我正在尝试对几个简单的 GET 请求进行单元测试,但无论我做什么,我都无法让测试失败。
如果我将 ('GET')
更改为 ('POST')
它将失败,但是所有 api 数据无论如何都会通过。
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { mockPhoneNumbers } from '../mocks/data/phoneNumbers.mock';
import { PhoneNumberApiService } from './phone-number-api.service';
describe('PhoneNumberApiService', () => {
let service: PhoneNumberApiService;
let httpTestingController: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [PhoneNumberApiService],
});
service = TestBed.get(PhoneNumberApiService);
httpTestingController = TestBed.get(HttpTestingController);
});
afterEach(() => {
// After every test, assert that there are no more pending requests.
httpTestingController.verify();
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should get the phone numbers successfully', () => {
service
.getPhoneNumbers()
.subscribe(phoneNumbers => {
expect(phoneNumbers).toEqual('bob');
expect(phoneNumbers[0].id).toEqual('b8bfea4d-a26f-9e4e-cbd4-39eb69cdaa58');
expect(phoneNumbers[1].friendlyName).toEqual('Dev Test');
});
const req = httpTestingController.expectOne('phoneNumbers');
expect(req.request.method).toEqual('GET');
req.flush(mockPhoneNumbers);
});
it('should get the phone number details successfully', () => {
const { id: phoneNumberId } = mockPhoneNumbers[0];
service
.getPhoneNumberDetails(phoneNumberId)
.subscribe(phoneNumber => expect(phoneNumber).toEqual(mockPhoneNumbers[0]));
const req = httpTestingController.expectOne(`phoneNumbers/${phoneNumberId}`);
expect(req.request.method).toEqual('GET');
req.flush('bob');
});
});
当然用模拟数据刷新请求然后期望模拟数据是 bob
是错误的。在底部测试中,使用 bob
刷新请求并期望数据等于数组中的第一个 phone 数字应该会失败。
关于你的测试的问题是你让你的 "it" 函数和预期异步没有明确告诉茉莉花.
您需要在其他地方使用 done 函数来告诉测试正在等待什么(查看 here 关于 jasmine 异步测试的好教程)
下面是一个基于您的代码的示例:
...
//Receive the done function like this
it('should get the phone numbers successfully', (done) => {
service
.getPhoneNumbers()
.subscribe(phoneNumbers => {
expect(phoneNumbers).toEqual('bob');
expect(phoneNumbers[0].id).toEqual('b8bfea4d-a26f-9e4e-cbd4-39eb69cdaa58');
expect(phoneNumbers[1].friendlyName).toEqual('Dev Test');
//Tell the test that only in here all the work was done
done();
});
const req = httpTestingController.expectOne('phoneNumbers');
expect(req.request.method).toEqual('GET');
req.flush(mockPhoneNumbers);
});
....
此外,为了回答