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

如何为V4版JavaScript Azure Durable Function编写单元测试?

Azure Durable Functions V4(JavaScript)单元测试指南

适用的测试工具

  • 官方适配库:@azure/durable-functions-testing,专为Durable Functions V4版本设计,提供编排器测试的模拟执行环境
  • 测试框架:使用jest或mocha编写测试用例
  • Mock工具:sinon用于模拟上下文、Durable Client等依赖项

测试编排器(AutoDeleteBackupOrchestrator)

编排器是生成器函数,需借助DurableOrchestrationTestHarness模拟执行流程,捕获并验证活动函数的调用逻辑。

示例测试代码

const { DurableOrchestrationTestHarness } = require('@azure/durable-functions-testing');
const df = require('durable-functions');
// 导入包含编排器的模块
const orchestratorModule = require('./path/to/your/orchestrator/file');

describe('AutoDeleteBackupOrchestrator', () => {
  let harness;

  beforeEach(() => {
    // 初始化测试环境
    harness = new DurableOrchestrationTestHarness(df.app);
    // 注册目标编排器
    harness.addOrchestrator('AutoDeleteBackupOrchestrator', orchestratorModule.AutoDeleteBackupOrchestrator);
    // Mock活动函数的返回值
    harness.mockActivity('AutoDeleteBackUpDeterminer', () => ['backup-db-01', 'backup-db-02']);
    harness.mockActivity('AutoDeleteBackUpActivity', (input) => `Deleted backup: ${input}`);
  });

  it('should call determiner activity and trigger parallel delete tasks', async () => {
    // 执行编排器测试
    await harness.runTest('AutoDeleteBackupOrchestrator', undefined);
    
    // 验证活动调用次数
    expect(harness.getState().calledActivities.length).toBe(3); // 1次判定活动 + 2次删除活动
    // 验证并行删除任务是否触发
    const deleteCalls = harness.getState().calledActivities.filter(a => a.name === 'AutoDeleteBackUpActivity');
    expect(deleteCalls.length).toBe(2);
    expect(deleteCalls[0].input).toBe('backup-db-01');
    expect(deleteCalls[1].input).toBe('backup-db-02');
  });
});

测试定时器触发器(AutoDeleteBackupTimerTrigger)

触发器的handler是普通异步函数,只需mockcontext和Durable Client的核心方法,直接调用handler即可验证逻辑。

示例测试代码

const sinon = require('sinon');
const df = require('durable-functions');
// 导入包含触发器的模块
const triggerModule = require('./path/to/your/trigger/file');

describe('AutoDeleteBackupTimerTrigger', () => {
  it('should start the target orchestrator successfully', async () => {
    // Mock Durable Client实例
    const mockClient = {
      startNew: sinon.stub().resolves('test-orchestration-id')
    };
    // Mock函数上下文
    const mockContext = {
      log: sinon.stub(),
      _extensionContext: { durableClient: mockClient }
    };
    // 替换df.getClient的默认实现
    const getClientStub = sinon.stub(df, 'getClient').returns(mockClient);

    // 调用触发器handler
    await triggerModule.AutoDeleteBackupTimerTrigger.handler({}, mockContext);

    // 验证编排器启动逻辑
    expect(mockClient.startNew.calledWith('AutoDeleteBackupOrchestrator')).toBe(true);
    // 验证日志输出
    expect(mockContext.log.calledWith('[Auto-Delete-Backup]: Started orchestration with ID: ', 'test-orchestration-id')).toBe(true);

    // 恢复原函数
    getClientStub.restore();
  });
});

测试活动函数

活动函数的handler是独立可调用的函数,直接传入测试参数即可验证输入输出逻辑:

示例测试代码

const { autoDeleteBackUpDeterminer, autoDeleteBackUpActivity } = require('../activity/autoDeleteBackUpActivity');

describe('AutoDeleteBackup Activities', () => {
  it('should return expected list of backups to delete', async () => {
    const result = await autoDeleteBackUpDeterminer();
    // 根据业务逻辑断言返回值
    expect(result).toEqual(expect.arrayContaining([])); // 替换为实际预期结果
  });

  it('should process backup deletion correctly', async () => {
    const testBackup = 'test-backup-db';
    const result = await autoDeleteBackUpActivity(testBackup);
    // 断言删除逻辑执行结果
    expect(result).toBeUndefined(); // 替换为实际预期返回值
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:26:10