[英]Unit testing injectable services
I am having problems while performing a simple unit test in my NX workspace.在我的 NX 工作区中执行简单的单元测试时遇到问题。 What I am attempting to do is to 1) configure TestBed and 2) Inject service.我正在尝试做的是 1)配置 TestBed 和 2)注入服务。 However, even if I use scaffolded dummy service, the test still fails as the injected service is said to be undefined
但是,即使我使用脚手架虚拟服务,测试仍然失败,因为据说注入的服务是undefined
的
test.service.ts测试服务.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class TestService {
constructor() { }
}
test.service.spec.ts test.service.spec.ts
import { TestBed } from '@angular/core/testing';
import { TestService } from './test.service';
describe('TestService', () => {
let service: TestService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ TestService ]
});
service = TestBed.inject(TestService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
Does anybody have an idea why is this happening?有人知道为什么会这样吗? What exactly is the problem here?这里到底有什么问题?
Edit: Yes, I do know I can create a mock.编辑:是的,我知道我可以创建一个模拟。 However, the issue still seems strange to me so I would like to get to the bottom of it rather than finding a workaround.但是,这个问题对我来说仍然很奇怪,所以我想深入了解它而不是找到解决方法。
Edit 2: Using ng test <project> --test-file=<filename>
directly yields the same results are using NXCLI to perform tests编辑 2:使用ng test <project> --test-file=<filename>
直接产生与使用 NXCLI 执行测试相同的结果
Edit 3: I shared my code on StackBlitz as requested: https://stackblitz.com/edit/ng-unittest-issue编辑 3:我按照要求在 StackBlitz 上分享了我的代码: https://stackblitz.com/edit/ng-unittest-issue
I've passed through the exact same issues, where the service was undefined
when being tested.我遇到了完全相同的问题,在测试时服务undefined
。 What solved my problem here were two things:在这里解决我的问题有两件事:
jest.mock('@angular/core/testing')
from your code.如果您使用的是 Jest,请确保从代码中删除jest.mock('@angular/core/testing')
。 This was required on earlier versions.这是早期版本所必需的。TestBed.configureTestingModule
.如果您的服务上有任何其他注入,则必须将它们添加到TestBed.configureTestingModule
下的“提供者”中。Here is a sample functional code and unit testing for a simple Http service, tested on Angular 9 and Angular 10:这是一个简单的 Http 服务的示例功能代码和单元测试,在 Angular 9 和 Angular 10 上进行了测试:
api.service.ts api.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class ApiService {
constructor(private http: HttpClient) {}
baseUrl = 'https://my-api-url.com';
//api/getId/:id
getDataById(id: number): Observable<DataSample[]> {
return this.http.get<DataSample[]>(`${this.baseUrl}/getId/${id}`);
}
}
export interface DataSample {
id: number;
name: string;
}
api.service.spec.ts api.service.spec.ts
import {
HttpClientTestingModule,
HttpTestingController,
} from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { ApiService, DataSample } from './api.service';
describe('ShiftDataApiService tests', () => {
let service: ApiService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [ApiService],
});
service = TestBed.inject(ApiService);
httpMock = TestBed.inject(HttpTestingController);
});
afterEach(() => httpMock.verify());
it('should return an Observable<DataSample[]>', () => {
expect(service).toBeTruthy();
const id: number = 1;
const mockResult: DataSample[] = [
{
id: 1,
name: 'name1',
},
{
id: 2,
name: 'name2',
},
];
const expectedUrl = `https://my-api-url.com/getId/${id}`;
service
.getDataById(id)
.subscribe((res) => expect(res).toBe(mockResult));
const req = httpMock.expectOne(expectedUrl);
expect(req.request.method).toBe('GET');
req.flush(mockResult);
});
});
Hope it helps希望能帮助到你
I think that's not correct for getting the service instance because you didn't provide your serivce.我认为获取服务实例是不正确的,因为您没有提供服务。
I used to get the instance like below:我曾经得到如下实例:
TestBed.configureTestingModule({
providers: [TestService]
});
service = TestBed.inject(TestService);
I think the issue is with your TestBed configuration so the way I would have approach this is我认为问题出在您的 TestBed 配置上,所以我将采用的方法是
import { TestBed } from '@angular/core/testing';
import { TestService } from './test.service';
describe('TestService', () => {
let service: TestService;
beforeEach(() => {
TestBed.configureTestingModule({
declaration:[], // your component here
imports: [],
providers: [TestService], // your services here
});
service = TestBed.get(TestService); // to get the service instance
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.