如何测试自定义 JavaScript Github 操作?

3 javascript node.js jestjs github-actions

我想创建一个 JavaScript Github 操作并使用 Jest 进行测试。根据文档,我开始解析输入,给出以下示例代码

import { getInput } from '@actions/core';

const myActionInput = getInput('my-key', { required: true });
Run Code Online (Sandbox Code Playgroud)

在开发过程中运行此代码会引发以下错误

需要输入但未提供:my-key

正如预期的那样,因为代码没有在 Github 操作环境中运行。但是否可以为此创建测试?例如

describe('getMyKey', () => {
  it('throws if the input is not present.', () => {
    expect(() => getMyKey()).toThrow();
  });
});
Run Code Online (Sandbox Code Playgroud)

如何使用上下文“伪造”/模拟这样的环境,以确保我的代码按预期工作?

ret*_*hab 5

您可以采取多种方法。

手动设置输入

输入作为带有前缀INPUT_和大写的环境变量传递给操作。知道这一点后,您只需在运行测试之前设置相应的环境变量即可。

在您的情况下,输入my-key需要作为名为 的环境变量出现INPUT_MY-KEY

这应该能让你的代码工作:

describe('getMyKey', () => {
  it('throws if the input is not present.', () => {
    process.env['INPUT_MY-KEY'] = 'my-value';
    expect(() => getMyKey()).toThrow();
  });
});
Run Code Online (Sandbox Code Playgroud)

使用 Jest 的嘲笑

您可以使用jest.mockorjest.spyOn从而模拟 的行为getInput

文档:ES6 类模拟

抽象动作

我不喜欢设置全局环境变量,因为一个测试可能会影响另一个测试,具体取决于它们的运行顺序。

另外,我不喜欢使用 进行嘲笑jest.mock,因为它感觉很神奇,而且我通常花费太多时间让它做我想做的事情。问题很难诊断。

似乎用更多一点的代码带来的所有好处是将操作拆分为一个函数,可以通过传入“全局”对象(如core.

// index.js
import core from '@actions/core';

action(core);
Run Code Online (Sandbox Code Playgroud)

// action.js
function action(core) {
   const myActionInput = core.getInput('my-key', { required: true });
}
Run Code Online (Sandbox Code Playgroud)

这使您可以很好地测试您的操作,如下所示:

// action.js
describe('getMyKey', () => {
  it('gets required key from input', () => {
    const core = {
      getInput: jest.fn().mockReturnValueOnce('my-value')
    };
    action(core);
    
    expect(core.getInput).toHaveBeenCalledWith('my-key', { required: true });
  });
});

Run Code Online (Sandbox Code Playgroud)

现在您可以说,如果输入不存在,我们不再测试操作是否抛出错误,但也要考虑您真正测试的内容:您正在测试如果输入不存在,核心操作是否抛出错误丢失的。在我看来,这不是您自己的代码,因此值得测试。您想要确保的是您getInput根据合同(即文档)正确调用该函数。