为什么取消测试失败?

huangapple go评论78阅读模式
英文:

Why onCancel test is failing?

问题

I've reviewed the code and the issue you're facing. It appears that the "handleCancel" function is not being called as expected when you simulate a click event on the Cancel button in your test.

Here are a few things you can check to debug this issue:

  1. Ensure that the "handleCancel" function is correctly passed as a prop to the ChooseLanguageModal component in your test.

  2. Double-check that the text content of the Cancel button in your component matches the text you're searching for in your test, which is "Cancel."

  3. Verify that there are no errors or exceptions being thrown within the handleCancel function that might prevent it from being executed.

  4. Confirm that there are no conflicting event handlers or components intercepting the click event on the Cancel button.

  5. Make sure that the render and act functions from the @testing-library/react library are used correctly in your tests.

If after checking these aspects, the issue persists, please provide more details about the component's structure and how it's used in your application so that I can assist you further.

英文:

I've written two tests; one to test the Download button and the other to test the Cancel button. Why is the Cancel test failing?

Here is the code I am trying to run two simple tests on the Download (handleDownload) and cancel (handleCancel) buttons.

import React from 'react';
import { Button, Modal, ModalFooter } from 'react-bootstrap';
import ReactDOM from 'react-dom';

import Select from 'controls/Select/Select';
import { getModalRoot } from 'sd/components/layout/admin/forms/FvReplaceFormModal/helpers';
import { DOWNLOAD_BUTTON_TEXT, CANCEL_BUTTON_TEXT } from 'sd/constants/ModalWindowConstants';

import 'sd/components/layout/admin/forms/FvReplaceFormModal/style.scss';
import type { SelectOption } from 'shared/types/General';

const { Body: ModalBody, Header: ModalHeader, Title: ModalTitle } = Modal;

export interface ChooseLanguageModalProps {
    languageList: SelectOption[];
    onDownloadLanguage: (value?: string) => void;
    onDownload: () => void;
    onCancel?: () => void;
}

const HEADER_TITLE = 'Choose language page';
const CHOOSE_LANGUAGE_LABEL = 'Choose language';

export const ChooseLanguageModal = (props: ChooseLanguageModalProps) => {
    const { languageList } = props;

    const onChangeLanguage = (value?: string | undefined) => {
        const { onDownloadLanguage } = props;
        onDownloadLanguage(value);
    };

    const handleCancel = async () => {
        await hideChooseLanguageModal();
    };

    const handleDownload = async () => {
        const { onDownload } = props;
        onDownload();

        await hideChooseLanguageModal();
    };

    return (
        <Modal
            show
            backdrop="static"
            animation={false}
            container={getModalRoot()}
            onHide={() => hideChooseLanguageModal()}
        >
            <ModalHeader closeButton>
                <ModalTitle>{HEADER_TITLE}</ModalTitle>
            </ModalHeader>
            <ModalBody>
                <div>
                    <p>This project has one or more languages set up in the Translation Manager.</p>
                    <p>
                        To download the translation in the BRD export, select one language from the drop-down below.
                        English will always be shown as the base language.
                    </p>
                    <p>
                        If a language is selected, additional columns will be added to display the appropriate
                        translation for labels, rules and text messages.
                    </p>
                    <p>You may click Download without selecting a language to export the default language.</p>
                </div>
                <div>{CHOOSE_LANGUAGE_LABEL}</div>
                <div>
                    <Select
                        clearable={false}
                        canEnterFreeText={false}
                        searchable={false}
                        options={languageList}
                        onChange={onChangeLanguage}
                    />
                </div>
            </ModalBody>
            <ModalFooter>
                <Button bsStyle="primary" onClick={handleDownload}>
                    {DOWNLOAD_BUTTON_TEXT}
                </Button>
                <Button onClick={handleCancel}>{CANCEL_BUTTON_TEXT}</Button>
            </ModalFooter>
        </Modal>
    );
};

export async function showChooseLanguageModal(props: ChooseLanguageModalProps): Promise<void> {
    await ReactDOM.render(<ChooseLanguageModal {...props} />, getModalRoot());
}

export async function hideChooseLanguageModal(): Promise<void> {
    const modalRoot = getModalRoot();
    modalRoot && ReactDOM.unmountComponentAtNode(modalRoot);
}

Here are the tests that I've written.

import { render, fireEvent, screen } from '@testing-library/react';
import React from 'react';
import { act } from 'react-dom/test-utils';

import { ChooseLanguageModal } from '../ChooseLanguageWindow.react';

describe('ChooseLanguageModal', () => {
    const languageList = [
        { id: '1', value: 'en', name: 'English' },
        { id: '2', value: 'fr', name: 'French' },
        { id: '3', value: 'es', name: 'Spanish' },
    ];
    const onDownloadLanguage = jest.fn();
    const handleDownload = jest.fn();
    const handleCancel = jest.fn();

    test('should call onDownload when download button is clicked', async () => {
        await act(async () => {
            render(
                <ChooseLanguageModal
                    languageList={languageList}
                    onDownloadLanguage={onDownloadLanguage}
                    onDownload={handleDownload}
                    onCancel={handleCancel}
                />
            );
        });

        const downloadButton = screen.getByText('Download');
        fireEvent.click(downloadButton);

        expect(handleDownload).toHaveBeenCalled();
    });

    test('should call onCancel when cancel button is clicked', async () => {
        await act(async () => {
            render(
                <ChooseLanguageModal
                    languageList={languageList}
                    onDownloadLanguage={onDownloadLanguage}
                    onDownload={handleDownload}
                    onCancel={handleCancel}
                />
            );
        });

        const cancelButton = screen.getByText('Cancel');
        fireEvent.click(cancelButton);

        expect(handleCancel).toHaveBeenCalled();
    });
});

You'll notice that both tests are closely identical, obviously except for the fireEvent. It fails every time.

ChooseLanguageModal › should call onCancel when cancel button is clicked

    expect(jest.fn()).toHaveBeenCalled()

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

      48 |         fireEvent.click(cancelButton);
      49 |
    > 50 |         expect(handleCancel).toHaveBeenCalled();
         |                              ^
      51 |     });
      52 | });
      53 |

I've tried running only the onCancel test but it still fails.

答案1

得分: 0

onCancel在您的ChooseLanguageModal组件中根本未被使用。它在类型中被接受,但从未传递给任何地方,也从未在您自己的组件中调用。您的测试当前正确失败,因为应用程序不按照测试规范工作。

按照您的期望调用它,可能意味着应该在handleCancel中:

const handleCancel = async () => {
    onCancel()
    await hideChooseLanguageModal();
};

希望这对您有所帮助。

英文:

onCancel is not used at all in your ChooseLanguageModal component. It is accepted in the types, but it is never passed to anything and never called inside of your own component either. Your test is currently correctly failing because the application doesn't work according to the test specification.

Call it as you expect, which was probably intended to be in handleCancel:

import React from 'react';
import { Button, Modal, ModalFooter } from 'react-bootstrap';
import ReactDOM from 'react-dom';

import Select from 'controls/Select/Select';
import { getModalRoot } from 'sd/components/layout/admin/forms/FvReplaceFormModal/helpers';
import { DOWNLOAD_BUTTON_TEXT, CANCEL_BUTTON_TEXT } from 'sd/constants/ModalWindowConstants';

import 'sd/components/layout/admin/forms/FvReplaceFormModal/style.scss';
import type { SelectOption } from 'shared/types/General';

const { Body: ModalBody, Header: ModalHeader, Title: ModalTitle } = Modal;

export interface ChooseLanguageModalProps {
    languageList: SelectOption[];
    onDownloadLanguage: (value?: string) => void;
    onDownload: () => void;
    onCancel?: () => void;
}

const HEADER_TITLE = 'Choose language page';
const CHOOSE_LANGUAGE_LABEL = 'Choose language';

export const ChooseLanguageModal = (props: ChooseLanguageModalProps) => {
    const { languageList, onCancel } = props;

    const onChangeLanguage = (value?: string | undefined) => {
        const { onDownloadLanguage } = props;
        onDownloadLanguage(value);
    };

    const handleCancel = async () => {
        onCancel()
        await hideChooseLanguageModal();
    };

    const handleDownload = async () => {
        const { onDownload } = props;
        onDownload();

        await hideChooseLanguageModal();
    };

    return (
        <Modal
            show
            backdrop="static"
            animation={false}
            container={getModalRoot()}
            onHide={() => hideChooseLanguageModal()}
        >
            <ModalHeader closeButton>
                <ModalTitle>{HEADER_TITLE}</ModalTitle>
            </ModalHeader>
            <ModalBody>
                <div>
                    <p>This project has one or more languages set up in the Translation Manager.</p>
                    <p>
                        To download the translation in the BRD export, select one language from the drop-down below.
                        English will always be shown as the base language.
                    </p>
                    <p>
                        If a language is selected, additional columns will be added to display the appropriate
                        translation for labels, rules and text messages.
                    </p>
                    <p>You may click Download without selecting a language to export the default language.</p>
                </div>
                <div>{CHOOSE_LANGUAGE_LABEL}</div>
                <div>
                    <Select
                        clearable={false}
                        canEnterFreeText={false}
                        searchable={false}
                        options={languageList}
                        onChange={onChangeLanguage}
                    />
                </div>
            </ModalBody>
            <ModalFooter>
                <Button bsStyle="primary" onClick={handleDownload}>
                    {DOWNLOAD_BUTTON_TEXT}
                </Button>
                <Button onClick={handleCancel}>{CANCEL_BUTTON_TEXT}</Button>
            </ModalFooter>
        </Modal>
    );
};

export async function showChooseLanguageModal(props: ChooseLanguageModalProps): Promise<void> {
    await ReactDOM.render(<ChooseLanguageModal {...props} />, getModalRoot());
}

export async function hideChooseLanguageModal(): Promise<void> {
    const modalRoot = getModalRoot();
    modalRoot && ReactDOM.unmountComponentAtNode(modalRoot);
}

huangapple
  • 本文由 发表于 2023年6月9日 05:43:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76435877.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定