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

如何将beforeEach中初始化的变量传递到闭包外的可复用测试函数

问题

我想写一个可复用的Jasmine测试函数,放在单独文件里,能接收参数以及effects和actions$变量,但这俩变量是在beforeEach里初始化的,直接传的话会是undefined。

现有测试代码如下:

let actions$: Subject<Action>;
let effects: CustomEffects;

beforeEach(() => {
  actions$ = new Subject<Action>();

  TestBed.configureTestingModule({
    providers: [
      CustomEffects,
      provideMockActions(() => actions$),
    ],
  });

  effects = TestBed.inject(CustomEffects);
});

testLoadingIndicators(
  simpleParamsPassedWithoutProblem,
  { effects, actions$ }, // 这里拿到的是undefined,undefined
);

最终目标是这个复用函数能包含describe和it语句,通过传入的参数执行逻辑,还能在多个测试文件里共享。之前用闭包的话只能在当前describe里定义,没法复用。

解决思路

思路1:传回调函数代替直接传变量

既然beforeEach是在每个测试用例执行前才初始化变量,那我们可以给复用函数传一个获取依赖的回调,让函数内部在测试执行时再调用回调拿最新的实例,而不是提前传未初始化的值。

复用函数定义(单独文件)

export function testLoadingIndicators(params: any, getDeps: () => { effects: CustomEffects; actions$: Subject<Action> }) {
  describe('Loading indicator 测试', () => {
    it('应该正确处理加载状态', () => {
      // 在测试执行时才获取已初始化的依赖
      const { effects, actions$ } = getDeps();
      
      // 这里写你的测试逻辑
      actions$.next(/* 测试用的action */);
      // 比如断言effects的输出、状态变化等
    });
  });
}

测试文件调用

let actions$: Subject<Action>;
let effects: CustomEffects;

beforeEach(() => {
  actions$ = new Subject<Action>();

  TestBed.configureTestingModule({
    providers: [
      CustomEffects,
      provideMockActions(() => actions$),
    ],
  });

  effects = TestBed.inject(CustomEffects);
});

// 传一个回调,在测试时才返回已初始化的变量
testLoadingIndicators(simpleParamsPassedWithoutProblem, () => ({ effects, actions$ }));

思路2:把初始化逻辑也封装进复用函数

如果不想在每个测试文件里写beforeEach初始化代码,可以把TestBed的配置也封装到复用函数里,让函数自己管理effects和actions$的生命周期。

复用函数定义(单独文件)

export function testLoadingIndicators(params: any, EffectClass: typeof CustomEffects) {
  describe('Loading indicator 测试', () => {
    let actions$: Subject<Action>;
    let effects: CustomEffects;

    beforeEach(() => {
      actions$ = new Subject<Action>();

      TestBed.configureTestingModule({
        providers: [
          EffectClass,
          provideMockActions(() => actions$),
        ],
      });

      effects = TestBed.inject(EffectClass);
    });

    it('应该正确处理加载状态', () => {
      // 直接用函数内部的effects和actions$
      actions$.next(params.testAction);
      // 执行断言逻辑
    });
  });
}

测试文件调用

// 只需要传参数和对应的Effect类就行,不用自己维护变量
testLoadingIndicators(simpleParamsPassedWithoutProblem, CustomEffects);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 20:08:34