You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular+Jest测试报错NG0203:无法实例化UserService求助

问题

团队统一使用Jest测试Angular项目,测试UserService时无法完成实例化,触发NG0203错误,怀疑问题出在依赖关联或配置层面。

测试代码

import { TestBed } from '@angular/core/testing';
import { ENVIRONMENT } from '../core';


describe('UserService', () => {
  let service: UserService;

  beforeEach(async() => {
    await TestBed.configureTestingModule({
        providers: [UserService,
            { provide: ENVIRONMENT,useValue: {
                apiUrl: '/api/',
                jwtTokenName: 'my.token',
              } }
        ]}).compileComponents();
    service = TestBed.inject(UserService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });

});

UserService代码

@Injectable({
    providedIn: 'root'
})
export class UserService
{
    private _user: ReplaySubject<User> = new ReplaySubject<User>(1);

    constructor(
      private _apiService: ApiService,
      private _socketService: SocketService,
    ) {
      this._socketService.emitter.subscribe((event: SocketEvent) => { this.onSocketEvent(event); });
    }
}

报错输出

FAIL  src/app/core/user/user.service.spec.ts
  ● UserService › should be created

    NG0203: inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with `EnvironmentInjector#runInContext`. Find more at https://angular.io/errors/NG0203
解决方案

NG0203错误的核心原因是依赖未正确提供,导致注入上下文失效。你的UserService构造函数依赖了ApiService和SocketService,但测试模块的providers中仅声明了UserService和ENVIRONMENT,未提供这两个关键依赖,因此实例化时触发注入错误。

解决方法一:手动提供依赖的模拟实现

在TestBed的providers中添加两个依赖的模拟对象,确保模拟对象包含UserService构造函数中用到的属性(比如SocketService的emitter):

import { Subject } from 'rxjs';

describe('UserService', () => {
  let service: UserService;

  beforeEach(async() => {
    // 模拟ApiService
    const mockApiService = {};
    // 模拟SocketService,构造函数中订阅了emitter,需提供Subject实例
    const mockSocketService = {
      emitter: new Subject<SocketEvent>()
    };

    await TestBed.configureTestingModule({
        providers: [
            UserService,
            { provide: ENVIRONMENT, useValue: { apiUrl: '/api/', jwtTokenName: 'my.token' } },
            { provide: ApiService, useValue: mockApiService },
            { provide: SocketService, useValue: mockSocketService }
        ]
    }).compileComponents();
    service = TestBed.inject(UserService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

解决方法二:简化测试配置(移除不必要的async/await)

Angular CLI项目中组件模板已预编译,无需调用compileComponents(),可简化测试代码,同时确保注入上下文正确:

import { Subject } from 'rxjs';

describe('UserService', () => {
  let service: UserService;

  beforeEach(() => {
    TestBed.configureTestingModule({
        providers: [
            UserService,
            { provide: ENVIRONMENT, useValue: { apiUrl: '/api/', jwtTokenName: 'my.token' } },
            { provide: ApiService, useValue: {} },
            { provide: SocketService, useValue: { emitter: new Subject<SocketEvent>() } }
        ]
    });
    service = TestBed.inject(UserService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

解决方法三:使用Jest自动模拟依赖

在测试文件顶部通过jest.mock自动生成依赖服务的模拟类,再在providers中声明使用:

// 替换为实际的文件路径
jest.mock('../../api.service');
jest.mock('../../socket.service');

describe('UserService', () => {
  let service: UserService;

  beforeEach(() => {
    TestBed.configureTestingModule({
        providers: [
            UserService,
            { provide: ENVIRONMENT, useValue: { apiUrl: '/api/', jwtTokenName: 'my.token' } },
            ApiService,
            SocketService
        ]
    });
    service = TestBed.inject(UserService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

注:自动生成的模拟类为空,若后续测试需要调用服务方法,需手动补充模拟实现。

内容的提问来源于stack exchange,提问作者Enrico Viappiani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 03:52:38