Я хочу создать действие JavaScript Github и использовать Jest для целей тестирования. На основе документы я начал анализировать ввод, учитывая следующий пример кода
import { getInput } from '@actions/core';
const myActionInput = getInput('my-key', { required: true });
Запуск этого кода во время разработки вызывает следующую ошибку
Input required and not supplied: my-key
как и ожидалось, потому что код не работает в среде действий Github. Но можно ли для этого создавать тесты? Например.
describe('getMyKey', () => {
it('throws if the input is not present.', () => {
expect(() => getMyKey()).toThrow();
});
});
Как я могу «подделать»/издеваться над такой средой с помощью контекста, чтобы убедиться, что мой код работает должным образом?
Есть несколько подходов, которые вы можете предпринять.
Входные данные передаются действиям как переменные среды с префиксом 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();
});
});
Вы можете использовать jest.mock
или jest.spyOn
и таким образом издеваться над поведением getInput
.
Документы: Макет класса ES6
Мне не нравится устанавливать глобальные переменные среды, потому что один тест может влиять на другой в зависимости от порядка их выполнения.
Кроме того, мне не нравится издеваться над jest.mock
, потому что это похоже на магию, и я обычно трачу слишком много времени на то, чтобы заставить его делать то, что я хочу. Проблемы трудно диагностировать.
Что, кажется, приносит все преимущества с небольшим количеством кода, так это разделение действия на функцию, которую можно вызывать, передавая «глобальные» объекты, такие как core
.
// index.js
import core from '@actions/core';
action(core);
// action.js
function action(core) {
const myActionInput = core.getInput('my-key', { required: true });
}
Это позволяет вам хорошо протестировать свои действия следующим образом:
// 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 });
});
});
Теперь вы можете сказать, что мы больше не проверяем, выдает ли действие ошибку, если входные данные отсутствуют, но также рассмотрим, что вы на самом деле тестируете: вы проверяете, выдает ли основное действие ошибку, если входные данные отсутствует. На мой взгляд, это не ваш собственный код и поэтому заслуживает тестирования. Все, что вы хотите убедиться, это то, что вы правильно вызываете функцию getInput
в соответствии с контрактом (то есть документами).