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

如何Mock @actions/github中的listComments函数?

如何Mock GitHub Action中@actions/github相关的listComments函数?

首先提醒下:你的代码里目前缺少octokit实例的初始化逻辑,得先补上类似const octokit = new Octokit({ auth: core.getInput('github-token') });的代码,不然运行时会报错。

下面是两种常用的Mock方案,以Jest测试框架为例:

方案一:直接Mock @octokit/rest的Octokit类

因为你直接导入了Octokit类,所以可以直接Mock整个类,让它返回带有模拟方法的实例:

import { runAction } from './你的动作文件路径';
import { Octokit } from '@octokit/rest';

// 全局Mock Octokit
jest.mock('@octokit/rest', () => {
  // 模拟listComments的返回值
  const mockListComments = jest.fn().mockResolvedValue([
    { id: 1, body: '测试评论1' },
    { id: 2, body: '测试评论2' }
  ]);
  // 模拟paginate方法,这里直接返回listComments的结果(需要复杂分页逻辑可调整)
  const mockPaginate = jest.fn().mockImplementation((fn) => fn());

  return {
    Octokit: jest.fn().mockImplementation(() => ({
      paginate: mockPaginate,
      rest: {
        issues: {
          listComments: mockListComments
        }
      }
    }))
  };
});

describe('runAction 测试', () => {
  it('应该获取并打印评论', async () => {
    // 监听console.log,避免测试时输出冗余内容
    const logSpy = jest.spyOn(console, 'log').mockImplementation();

    await runAction();

    // 断言Octokit被实例化
    expect(Octokit).toHaveBeenCalled();
    // 获取实例,断言listComments的调用参数正确
    const octokitInstance = Octokit.mock.instances[0];
    expect(octokitInstance.rest.issues.listComments).toHaveBeenCalledWith({
      owner: '1',
      repo: 'my_repo',
      issue_number: 1,
      per_page: 100
    });
    // 断言console.log输出了模拟的评论数据
    expect(logSpy).toHaveBeenCalledWith([
      { id: 1, body: '测试评论1' },
      { id: 2, body: '测试评论2' }
    ]);

    // 恢复console.log
    logSpy.mockRestore();
  });
});

方案二:如果使用@actions/github的getOctokit方法

如果你的代码是通过github.getOctokit()获取octokit实例的(GitHub Action推荐用法),可以直接Mock @actions/github模块:

import { runAction } from './你的动作文件路径';
import * as github from '@actions/github';

// Mock getOctokit方法
jest.mock('@actions/github', () => ({
  getOctokit: jest.fn().mockReturnValue({
    paginate: jest.fn().mockResolvedValue([
      { id: 1, body: '测试评论1' },
      { id: 2, body: '测试评论2' }
    ]),
    rest: {
      issues: {
        listComments: jest.fn().mockResolvedValue([
          { id: 1, body: '测试评论1' },
          { id: 2, body: '测试评论2' }
        ])
      }
    }
  })
}));

describe('runAction 测试', () => {
  it('应该成功获取评论', async () => {
    const logSpy = jest.spyOn(console, 'log').mockImplementation();
    
    await runAction();

    expect(github.getOctokit).toHaveBeenCalled();
    expect(logSpy).toHaveBeenCalledWith([
      { id: 1, body: '测试评论1' },
      { id: 2, body: '测试评论2' }
    ]);

    logSpy.mockRestore();
  });
});

关键注意点

  • Mock时要覆盖paginate和listComments两个方法,因为你的代码用了octokit.paginate来调用listComments
  • 要确保模拟的参数和业务代码一致,原代码里的参数写法有问题,listComments的正确参数应该是owner、repo、issue_number,而非直接传1、"my_repo"、1,得先修正业务代码的参数格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:20:24