英文:
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:
-
Ensure that the "handleCancel" function is correctly passed as a prop to the
ChooseLanguageModal
component in your test. -
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."
-
Verify that there are no errors or exceptions being thrown within the
handleCancel
function that might prevent it from being executed. -
Confirm that there are no conflicting event handlers or components intercepting the click event on the Cancel button.
-
Make sure that the
render
andact
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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论