reactjs 检查react-testing-library中的按钮是否已禁用

ylamdve6  于 2023-05-17  发布在  React
关注(0)|答案(9)|浏览(116)

我有一个React组件,它生成了一个按钮,其内容包含一个像这样的<span>元素:

function Click(props) {
    return (
        <button disable={props.disable}>
            <span>Click me</span>
        </button>
    );
}

我想使用react-testing-librarymocha + chai来测试这个组件的逻辑。
我目前遇到的问题是getByText("Click me")选择器返回<span> DOM节点,但对于测试,我需要检查<button>节点的disable属性。处理这样的测试用例的最佳实践是什么?我看到了几个解决方案,但它们听起来都有点不对劲:
1.将data-test-id用于<button>元素
1.选择<Click />组件的祖先之一,然后选择按钮within(...) this scope
1.单击带有fireEvent的所选元素,并检查是否没有发生任何事情
你能建议一个更好的方法吗?

zzwlnbp8

zzwlnbp81#

按钮禁用时声明

您可以使用toHaveAttributeclosest来测试它。

import { render } from '@testing-library/react';

const { getByText } = render(Click);
expect(getByText(/Click me/i).closest('button')).toHaveAttribute('disabled');

toBeDisabled

expect(getByText(/Click me/i).closest('button')).toBeDisabled();

按钮启用时Assert

要检查按钮是否已启用,请按如下方式使用not

expect(getByText(/Click me/i).closest('button')).not.toBeDisabled();
pcrecxhr

pcrecxhr2#

你可以使用@testing-library/jest-dom中的toBeDisabled(),它是一个自定义的jest matcher,用来测试DOM的状态:
https://github.com/testing-library/jest-dom
示例:

<button>Submit</button>
expect(getByText(/submit/i)).toBeDisabled()
qlfbtfca

qlfbtfca3#

对于正在寻找按钮未禁用的测试的人。

import { render } from '@testing-library/react';

const { getByText } = render(Click);
expect(getByText(/Click me/i).getAttribute("disabled")).toBe(null)
vzgqcmou

vzgqcmou4#

我会礼貌地说你正在测试一个实现细节,这是react-testing-library不鼓励的。
你的测试越像你的软件的使用方式,它们就能给予你越多的信心。
如果一个按钮被禁用,用户不会看到一个禁用的 prop ,相反,他们看到什么也没有发生。如果一个按钮被启用,用户不会看到一个被禁用的 prop 的遗漏,相反,他们会看到一些事情发生。
我认为你应该测试这个:

const Button = (props) => (
  <button 
    type="submit" 
    onClick={props.onClick} 
    disabled={props.disabled}
  >
    Click me
  </button>
);

describe('Button', () => {
  it('will call onClick when enabled', () => {
    const onClick = jest.fn();
    render(<Button onClick={onClick} disabled={false} />);
    userEvent.click(getByRole('button', /click me/i));
    expect(onClick).toHaveBeenCalledTimes(1);
  });

  it('will not call onClick when disabled', () => {
    const onClick = jest.fn();
    render(<Button onClick={onClick} disabled={true} />);
    userEvent.click(getByRole('button', /click me/i));
    expect(onClick).not.toHaveBeenCalled();
  });
})
ijnw1ujt

ijnw1ujt5#

toHaveAttribute是使用属性的好选择。

<button data-testid="ok-button" type="submit" disabled>ok</button>

const button = getByTestId('ok-button')
//const button = getByRole('button');

expect(button).toHaveAttribute('disabled')
expect(button).toHaveAttribute('type', 'submit')
expect(button).not.toHaveAttribute('type', 'button')

expect(button).toHaveAttribute('type', expect.stringContaining('sub'))
expect(button).toHaveAttribute('type', expect.not.stringContaining('but'))

希望这会有帮助。

d8tt03nd

d8tt03nd6#

您可以使用@testing-library/react测试按钮的禁用属性,如下所示。
例如:

import { render } from '@testing-library/react';

   const {getByText} = render(<Click/>)

   expect(getByText('Click me').closest('button').disabled).toBeTruthy()
xdyibdwo

xdyibdwo7#

解决这个问题的另一种方法是按角色抓取并检查innerHTML,如:

const { getByRole } = render(<Click />)
const button = getByRole('button')

// will make sure the 'Click me' text is in there somewhere
expect(button.innerHTML).toMatch(/Click me/))

对于您的特定情况,这不是最好的解决方案,但如果您必须处理不是实际按钮的按钮组件,则可以将其放在后袋中,例如,
<div role="button"><span>Click Me</span></div>

ulydmbyx

ulydmbyx8#

我的解决方案,在我看来,这个案件涵盖了什么是必要的。检查按钮已禁用,因此toHaveBeenCalledTimes必须接收0

test('Will not call onClick when disabled', () => {
        const mockHandler = jest.fn()

        render(<Button title="Disabled account" disabled={true} onClick={mockHandler} />)
        const button = screen.getByText("Disabled account")
        fireEvent.click(button)

        expect(mockHandler).toHaveBeenCalledTimes(0)
        expect(button).toHaveProperty('disabled', true)
    })
5q4ezhmt

5q4ezhmt9#

当前答案:

expect(await screen.findByRole('button', { name: 'Click me' })).toBeEnabled();

相关问题