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

如何用Jest测试DatadogService.sendMetric的Promise拒绝场景

测试DatadogService.sendMetric() Promise拒绝场景的问题

问题背景

我想要测试DatadogService.sendMetric()方法的Promise拒绝场景,但运行测试后报错,相关代码和错误信息如下:

DatadogService.ts

import { client, v2 } from "@datadog/datadog-api-client";
import { getRootLogger } from "@backstage/backend-common";
import { Logger } from 'winston';

export class DatadogService {
    private readonly logger: Logger;
    apiInstance: v2.MetricsApi;
    
    constructor(apiKey : string | undefined) {
      const configurationOpts = {
            authMethods: {
              apiKeyAuth: apiKey
            },
      };  
      const configuration = client.createConfiguration(configurationOpts);
      this.apiInstance = new v2.MetricsApi(configuration);
      this.logger = getRootLogger();
    }
  
    async sendMetric(metricName: string, tags: string[]) : Promise<any> {
      const params: v2.MetricsApiSubmitMetricsRequest = {
            body: {
              series: [
                {
                  metric: metricName,
                  type: 1,
                  points: [
                    {
                      timestamp: Math.round(new Date().getTime() / 1000),
                      value: 1,
                    },
                  ],
                  tags: tags,
                },
              ],
            },
        };
        try {
            await this.apiInstance.submitMetrics(params);
            this.logger.info(`Metric ${metricName} submitted data ${JSON.stringify(params)}`);
            return Promise.resolve('metric sent');
        } catch(error) {
            this.logger.error(`Metric submission failed for ${metricName} with data ${JSON.stringify(params)}`);
            return Promise.reject('Error occurred while submitting metric : ' + metricName);
        }
    };
}

DatadogService.test.ts

import { DatadogService } from './DatadogService';
import { constructTagsArray } from './utils';

describe('DatadogService', () => {
  beforeEach(() => {
    jest.resetAllMocks();
  });

  it('send metrics to throw error due to invalid key ', async () => {
    const DATADOG_API_KEY = 'DUMMY_API_KEY';
    const tags = {
      tagA: 'tagAValue',
      tagB: 'tagBValue'
    };
    const response = await new DatadogService(DATADOG_API_KEY).sendMetric('datadogMetricName', constructTagsArray(tags));
    const rejectMessage = 'Error occurred while submitting metric : datadogMetricName'
    await expect(response).rejects.toThrow(rejectMessage);
  });
  
});

测试运行错误

DatadogService › send metrics to throw error due to invalid key 

    thrown: "Error occurred while submitting metric : datadogMetricName"

       8 |   });
       9 |
    > 10 |   it('send metrics to throw error due to invalid key ', async () => {
         |   ^
      11 |     const DATADOG_API_KEY = 'DUMMY_API_KEY';
      12 |     const tags = {
      13 |       tagA: 'tagAValue ',

      at service/DatadogService.test.ts:10:3
      at Object.<anonymous> (service/DatadogService.test.ts:5:1)

正确的测试写法

问题出在你直接用await调用了会拒绝的Promise,导致错误直接抛出,没有被expect捕获。正确的做法是不要提前await,而是将Promise直接传入expect,通过rejects断言来验证拒绝行为。

修改后的测试代码如下:

import { DatadogService } from './DatadogService';
import { constructTagsArray } from './utils';

describe('DatadogService', () => {
  beforeEach(() => {
    jest.resetAllMocks();
  });

  it('send metrics to throw error due to invalid key ', async () => {
    const DATADOG_API_KEY = 'DUMMY_API_KEY';
    const tags = {
      tagA: 'tagAValue',
      tagB: 'tagBValue'
    };
    const rejectMessage = 'Error occurred while submitting metric : datadogMetricName';
    const service = new DatadogService(DATADOG_API_KEY);

    // 直接对Promise使用expect.rejects断言
    await expect(service.sendMetric('datadogMetricName', constructTagsArray(tags)))
      .rejects.toThrow(rejectMessage);
  });
});

额外优化建议

在async函数里,不需要手动返回Promise.resolve()或Promise.reject(),直接返回值或抛出错误即可,async函数会自动处理成Promise:

async sendMetric(metricName: string, tags: string[]) : Promise<any> {
  const params: v2.MetricsApiSubmitMetricsRequest = {
        body: {
          series: [
            {
              metric: metricName,
              type: 1,
              points: [
                {
                  timestamp: Math.round(new Date().getTime() / 1000),
                  value: 1,
                },
              ],
              tags: tags,
            },
          ],
        },
    };
    try {
        await this.apiInstance.submitMetrics(params);
        this.logger.info(`Metric ${metricName} submitted data ${JSON.stringify(params)}`);
        return 'metric sent'; // 直接返回值,自动包装为resolved的Promise
    } catch(error) {
        this.logger.error(`Metric submission failed for ${metricName} with data ${JSON.stringify(params)}`);
        throw `Error occurred while submitting metric : ${metricName}`; // 直接抛出错误,自动包装为rejected的Promise
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:05:28