Инъекционные услуги модульного тестирования
У меня возникли проблемы при выполнении простого модульного теста в моем рабочем пространстве NX. Что я пытаюсь сделать, так это 1) настроить TestBed и 2) внедрить службу. Однако, даже если я использую фиктивную службу с подмостками, тест все равно не проходит, так как внедренная служба называетсяundefined
test.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class TestService {
constructor() { }
}
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();
});
});
Кто-нибудь знает, почему это происходит? В чем именно проблема?
Изменить: Да, я знаю, что могу создать макет. Однако проблема все еще кажется мне странной, поэтому я хотел бы разобраться в ней, а не искать обходной путь.
Изменить 2: Использованиеng test <project> --test-file=<filename>
напрямую дает те же результаты, что и при использовании NXCLI для выполнения тестов
Изменить 3: я поделился своим кодом на StackBlitz по запросу: https://stackblitz.com/edit/ng-unittest-issue
2 ответа
Я прошел через те же проблемы, когда был
undefined
при тестировании. Здесь мою проблему решили две вещи:
- Если вы используете Jest, убедитесь, что вы удалили
jest.mock('@angular/core/testing')
из вашего кода. Это требовалось в более ранних версиях. - Если у вас есть какие-либо другие инъекции в вашей службе, вы должны добавить их в "поставщики" в разделе
TestBed.configureTestingModule
.
Вот пример функционального кода и модульного тестирования для простой службы Http, протестированных на Angular 9 и Angular 10:
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
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);
});
});
Надеюсь, поможет
Я думаю, что это неправильно для получения экземпляра службы, потому что вы не предоставили свою услугу.
Раньше я получал экземпляр, как показано ниже:
TestBed.configureTestingModule({
providers: [TestService]
});
service = TestBed.inject(TestService);
Я думаю, что проблема связана с вашей конфигурацией 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();
});
});