Проверка, вызвана ли функция внутри другой функции. Jest - PullRequest
2 голосов
/ 30 апреля 2020

Я пишу действие Redux для выполнения модульного теста a, но у меня возникли проблемы с вызовом фиктивной функции внутри теста. Я полагаю, что правильно смоделировал completeRegistration, импортировав модуль, в котором он объявлен, и затем смоделировав функцию из ссылки на модуль, но Джест говорит, что функция не вызывается, несмотря на оператор журнала консоли, подтверждающий, что условие verified.data.success Это true.

Есть идеи, что я делаю не так? Спасибо

auth. js

export const verifyEmail = ({
    originalCode,
    confirmCode,
    token
}) => async dispatch => {
    try {
        const body = JSON.stringify({
            originalCode,
            confirmCode,
            registering: true
        });
        const verified = await axios.post("/api/email/verify", body, config);
        if (verified.data.success) {
            console.log("Success!") // logs "Success!"
            completeRegistration(token); // test is to find out if this function gets called
        } else {
            return { msg: "Code did not match, please try again" };
        }
    } catch (err) {
        dispatch({
            type: REGISTER_FAILED
        });
    }
};

auth.test. js

import * as auth from "../../actions/auth";

const originalCompleteReg = auth.completeRegistration;

describe("verifyEmail action", () => {
    let verifyData;
    beforeEach(() => {
        verifyData = {
            originalCode: "1234546",
            confirmCode: "1234546",
            token: "87618g1u8ojb98k3jb12i3kwdbcjwvbbi92ueg29eubv" // fake data :p
        };
        auth.completeRegistration = jest.fn(() => auth.completeRegistration);
        moxios.install();
    });

    afterEach(() => {
        auth.completeRegistration = originalCompleteReg;
        moxios.uninstall();
    });

    it("calls completeRegistration function if successful", async () => {
        moxios.wait(() => {
            const request = moxios.requests.mostRecent();
            request.respondWith({
                status: 200,
                response: { success: true }
            });
        });

        const store = mockStore({ payload: {} });

        await store.dispatch(auth.verifyEmail(verifyData));
        expect(auth.completeRegistration).toBeCalled();
    });
});

Выход

verifyEmail action › calls completeRegistration function if successful

    expect(jest.fn()).toBeCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

1 Ответ

1 голос
/ 01 мая 2020

Проблема в том, что вы не насмехаетесь над внутренним значением completeRegistration, используемым verifyEmail в модуле auth, а экспортируемым значением.

При импорте модуля вы получаете объект со ссылками на функции модуля. Если вы перезаписываете значение в требуемом модуле, ваша собственная ссылка перезаписывается, но реализация сохраняет исходную ссылку.

Итак, в вашем случае, если вы вызовете auth.completeRegistration в своем тестовом файле, вы вызовете высмеянная версия. Но при вызове auth.verifyEmail (который внутренне вызывает completeRegistration), ссылка completeRegistration, на которую он ссылается, не является вашей перезаписанной версией.

Я думаю, вам не следует проверять, что вызывается ваш метод completeRegistration ( в конце концов, это деталь реализации). Вместо этого вы должны проверить, что ваш метод ведет себя так, как ожидалось (то есть поведение completeRegistration имеет, будь то перенаправление на другую страницу, выполнить дополнительный запрос, сохранить повар ie и т. Д. c). Таким образом, вы будете насмехаться над API, который используется в completeRegistration, но не над самим методом.

При этом, если вы хотите проверить, что completeRegistration вызывается, у вас все еще есть пара options.

Использовать babel rewire plugin

Вам нужно будет установить плагин и добавить его в свою конфигурацию babel. После этого ваш тест будет выглядеть так:

import AuthModule from '../../actions/auth';
import * as auth from '../../actions/auth';

describe('verifyEmail action', () => {
    let verifyData;

    beforeEach(() => {
        verifyData = {
            originalCode: '1234546',
            confirmCode: '1234546',
            token: '87618g1u8ojb98k3jb12i3kwdbcjwvbbi92ueg29eubv'
        };
        moxios.install();
    });

    afterEach(() => {
        moxios.uninstall();
    });

    it('calls completeRegistration function if successful', async () => {
        moxios.wait(() => {
            const request = moxios.requests.mostRecent();
            request.respondWith({
                status: 200,
                response: { success: true }
            });
        });

        const mockFn = jest.fn();
        AuthModule.__Rewire__('completeRegistration', mockFn);

        const store = mockStore({ payload: {} });

        await store.dispatch(auth.verifyEmail(verifyData));
        expect(mockFn).toHaveBeenCalled();
        AuthModule.__ResetDependency__('completeRegistration');
    });
});

Разделение функций в разных файлах

Вы можете создать отдельный модуль для функции completeRegistration , Таким образом, поскольку ваш auth. js должен будет импортировать модуль, вы сможете смоделировать модуль, используя возможности jest.mock.

...