Я использую тестовый код в машинописном тексте, использую шутку. Пожалуйста, научите меня, как издеваться над getData, чтобы вернуть ожидаемое значение. Мой код, как показано ниже:
// File util.ts
export const getData = async () => {
// Todo something
return data;
}
// File execution.ts import { getData } from './util';
function execute()
{
// todo something
const data = await getData();
// todo something
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Попробуйте следующее в своем тестовом файле. Импортируйте функцию из модуля.
import { getData } from './util';
Затем смоделируйте модуль с функцией и ее возвращаемым значением после всех операторов импорта.
jest.mock('./util', () => ({ getData: jest.fn() }))
getData.mockReturnValue("abc");
Затем используйте его в своих тестах.
Проблема в том, что ваша функция возвращает обещание. В зависимости от того, как вы его используете, есть несколько способов издеваться над ним.
Самый простой способ — смоделировать его напрямую, но тогда он всегда будет возвращать одно и то же значение:
// note, the path is relative to your test file
jest.mock('./util', () => ({ getData: () => 'someValue' }));
Если вы хотите протестировать как решенный, так и отклоненный случай, вам нужно имитировать getData, чтобы он вернул шпиона, где вы позже можете изменить реализацию, используя mockImplementation. Вам также нужно использовать async/await, чтобы тест работал, взгляните на документы об асинхронном тестировании:
import { getData } from './util';
jest.mock('./util', () => ({ getData: ()=> jest.fn() }));
it('success case', async () => {
const result = Promise.resolve('someValue');
getData.mockImplementation(() => result);
// call your function to test
await result; // you need to use await to make jest aware of the promise
});
it('error case', async () => {
const result = Promise.reject(new Error('someError'));
getData.mockImplementation(() => result);
// call your function to test
await expect(result).rejects.toThrow('someError');
});
Поскольку имитировать функции-выражения может быть очень сложно, я привожу полный пример ниже.
Сценарий
Допустим, мы хотим протестировать некоторый код, который выполняет какой-либо вызов REST, но мы не хотим, чтобы был сделан фактический вызов REST:
// doWithApi.ts
export const doSomethingWithRest = () => {
post("some-url", 123);
}
Где post — это функциональное выражение в отдельном файле:
// apiHelpers.ts
export const post = (url: string, num: number) => {
throw Error("I'm a REST call that should not run during unit tests!");
}
Настраивать
Поскольку функция post используется напрямую (а не передается в качестве параметра), мы должны создать фиктивный файл, который Jest сможет использовать во время тестов в качестве замены настоящей функции post:
// __mocks__/apiHelpers.ts
export const post = jest.fn();
Шпионить и тестировать
Теперь, наконец, внутри самого теста мы можем сделать следующее:
// mockAndSpyInternals.test.ts
import {doSomethingWithRest} from "./doWithApi";
afterEach(jest.clearAllMocks); // Resets the spy between tests
jest.mock("./apiHelpers"); // Replaces runtime functions inside 'apiHelpers' with those found inside __mocks__. Path is relative to current file. Note that we reference the file we want to replace, not the mock we replace it with.
test("When doSomethingWithRest is called, a REST call is performed.", () => {
// If we want to spy on the post method to perform assertions we must add the following lines.
// If no spy is wanted, these lines can be omitted.
const apiHelpers = require("./apiHelpers");
const postSpy = jest.spyOn(apiHelpers, "post");
// Alter the spy if desired (e.g by mocking a resolved promise)
// postSpy.mockImplementation(() => Promise.resolve({..some object}))
doSomethingWithRest();
expect(postSpy).toBeCalledTimes(1)
expect(postSpy).toHaveBeenCalledWith("some-url", 123);
});
Примеры сделаны с использованием Jest 24.9.0 и Typescript 3.7.4.
Использование
.rejectsпредпочтительнее для проверки случая отклонения, чтобы избежать ложных срабатываний от try/catch. (Как минимум вам нужно будет использоватьexpect.assertions, чтобы убедиться, что тест не пройден, еслиPromiseразрешится)