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

如何为含BehaviorSubject的Angular CalendarDomainService编写单元测试?

Angular CalendarDomainService 单元测试实现指导

我有一个CalendarDomainService服务,核心包含基于BehaviorSubject的可观测属性calendarWeek$和用于更新值的setCalendarWeek方法,服务代码如下:

calendar-domain.service.ts

@Injectable()
export class CalendarDomainService {
  private _calendarWeek = new BehaviorSubject<CalendarWeekTo | null>(null);
  get calendarWeek$(): Observable<CalendarWeekTo | null> {
    return this._calendarWeek.asObservable();
  }

  setCalendarWeek(calendarWeek: CalendarWeekTo): void {
    this._calendarWeek.next(calendarWeek);
  }
}

目前我已编写基础单元测试,但不清楚如何测试上述两个核心成员,现有测试代码如下:

calendar-domain.service.spec.ts

import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
import { TestBed } from '@angular/core/testing';

import { CalendarDomainService } from './calendar-domain.service';

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

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [CalendarDomainService],
            schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
        });
        service = TestBed.inject(CalendarDomainService);
    });

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

测试实现方案

针对calendarWeek$和setCalendarWeek,我们可以编写两个针对性的测试用例,借助RxJS工具验证可观测对象的行为:

1. 测试calendarWeek$的初始值

BehaviorSubject会在订阅时立即推送当前值,我们可以通过firstValueFrom异步获取初始值并验证。

2. 测试setCalendarWeek的更新逻辑

调用方法传入测试数据后,订阅calendarWeek$验证是否收到了正确的更新值。

以下是完整的测试代码:

import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { firstValueFrom } from 'rxjs';

import { CalendarDomainService } from './calendar-domain.service';
// 若项目中已定义CalendarWeekTo,可直接导入,此处为模拟测试类型
interface CalendarWeekTo {
  weekNumber: number;
  year: number;
}

describe('CalendarDomainService', () => {
    let service: CalendarDomainService;
    // 定义测试用模拟数据
    const testCalendarWeek: CalendarWeekTo = { weekNumber: 20, year: 2024 };

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [CalendarDomainService],
            schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
        });
        service = TestBed.inject(CalendarDomainService);
    });

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

    it('should emit null as initial value from calendarWeek$', async () => {
        const initialValue = await firstValueFrom(service.calendarWeek$);
        expect(initialValue).toBeNull();
    });

    it('should update calendarWeek$ value when setCalendarWeek is called', async () => {
        service.setCalendarWeek(testCalendarWeek);
        const updatedValue = await firstValueFrom(service.calendarWeek$);
        expect(updatedValue).toEqual(testCalendarWeek);
    });
});

代码说明

  • 使用firstValueFrom(RxJS 7+推荐)异步获取可观测对象的第一个值,避免回调嵌套,让测试代码更简洁。
  • 模拟CalendarWeekTo类型用于生成测试数据,项目中已有定义可直接替换为导入语句。
  • 第二个测试用例先调用更新方法,再验证calendarWeek$是否推送了正确的测试数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:40:55