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

如何测试带有服务依赖与构造参数的Angular普通类?

如何测试带有服务依赖和独立构造参数的Angular普通类

问题背景

测试普通类MyClass时,参照组件测试方案配置TestBed后出现错误:

Unexpected value 'MyClass' imported by the module 'DynamicTestModule'. Please add a @NgModule annotation.

相关代码:

my-service.service.ts

@Injectable({
    providedIn: 'root',
})
export class MyService { ... }

my-class.ts

import { inject } from '@angular/core';
import { MyService } from './my-service.service';

export class MyClass {
    private _myService: MyService = inject(MyService);
    private _name: string;

    constructor(name: string) {
        this._name = name;
    }
}

解决方案

普通类并非Angular的组件/指令/管道,不能添加到TestBed的declarations或imports配置中。需利用Angular的注入上下文来创建类实例,同时处理服务依赖。

方法一:使用TestBed.runInInjectionContext创建实例(推荐)

通过TestBed配置依赖,再在注入上下文内创建类实例,确保inject()能正常获取服务:

import { TestBed } from '@angular/core/testing';
import { MyService } from './my-service.service';
import { MyClass } from './my-class';

describe('MyClass', () => {
  let myServiceSpy: jasmine.SpyObj<MyService>;

  beforeEach(() => {
    // 创建MyService的Spy对象,用于模拟服务行为
    myServiceSpy = jasmine.createSpyObj('MyService', ['yourMethodName']);

    // 配置TestBed,提供Mock服务替代真实服务
    TestBed.configureTestingModule({
      providers: [
        { provide: MyService, useValue: myServiceSpy }
      ]
    });
  });

  it('should initialize with correct name and injected service', () => {
    // 在Angular注入上下文内创建MyClass实例
    const instance = TestBed.runInInjectionContext(() => {
      return new MyClass('test-user');
    });

    expect(instance).toBeTruthy();
    // 验证构造参数是否生效
    expect(instance['_name']).toBe('test-user');
    // 验证服务是否被正确注入
    expect(instance['_myService']).toBe(myServiceSpy);
  });
});

方法二:直接注入服务后创建实例

若无需复杂Mock,可直接从TestBed获取服务实例,再在注入上下文内创建类:

import { TestBed } from '@angular/core/testing';
import { MyService } from './my-service.service';
import { MyClass } from './my-class';

describe('MyClass', () => {
  let myService: MyService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    // 获取真实的MyService实例(或替换为Mock)
    myService = TestBed.inject(MyService);
  });

  it('should work with real service', () => {
    const instance = TestBed.runInInjectionContext(() => new MyClass('test-name'));
    
    expect(instance['_name']).toBe('test-name');
    // 可调用服务方法验证交互
    // myService.someMethod();
    // expect(...).toBe(...);
  });
});

错误原因说明

之前的配置错误将普通类MyClass添加到了TestBed的imports或declarations中,而这些配置项仅支持Angular的模块、组件、指令、管道类,普通类无法被识别,因此抛出@NgModule相关错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 11:03:29