如何测试一个组件是否以另一个组件作为参数调用函数 prop?
How to test that a component calls a function prop with another component as argument?
我有一个组件接收一个函数作为 prop 并将渲染的元素传递给它,挂载:
function MyComponent(props) {
useEffect(() => {
props.onHeaderChange(<button>Back</button>)
}, [])
return (<div>My Component</div>)
}
我想编写一个测试来检查后退按钮是否通过:
test("it renders the back button", () => {
const onHeaderChange = jest.fn()
const { getByText } = render(
<MyComponent {...props} onHeaderChange={onHeaderChange} />
)
expect(onHeaderChange).toHaveBeenCalledWith("How to test for the back button here?")
})
但我不确定 jest / react 测试库语法是什么?
有两种解决方法:
选项 1. 将 JSX 传递给 toHaveBeenCalledWith
方法就足够了。为什么?因为 JSX 是 React.createElement()
方法的语法糖。使用 JSX 编写的代码将转换为使用 React.createElement()
。它的 return 值只是一个 JavaScript 对象。
index.tsx
:
import React, { useEffect } from 'react';
export function MyComponent(props) {
useEffect(() => {
props.onHeaderChange(<button>Back</button>);
}, []);
return <div>My Component</div>;
}
index.test.tsx
:
import { render } from '@testing-library/react';
import React from 'react';
import { MyComponent } from '.';
describe('71995270', () => {
test('it renders the back button', () => {
const onHeaderChange = jest.fn();
render(<MyComponent onHeaderChange={onHeaderChange} />);
const expectedElement = React.createElement('button', null, 'Back');
console.log('expectedElement: ', expectedElement);
expect(onHeaderChange).toHaveBeenCalledWith(expectedElement);
expect(onHeaderChange).toHaveBeenCalledWith(<button>Back</button>);
});
});
PASS Whosebug/71995270/index.test.tsx (14.782 s)
71995270
✓ it renders the back button (42 ms)
console.log
expectedElement: {
'$$typeof': Symbol(react.element),
type: 'button',
key: null,
ref: null,
props: { children: 'Back' },
_owner: null,
_store: {}
}
at Object.<anonymous> (Whosebug/71995270/index.test.tsx:11:13)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 16.871 s
选项 2. 使用 mockImplementation
模拟 onHeaderChange
函数并获取测试用例中的 button
元素,render
它并断言。
test('it renders the back button - 2', () => {
let buttonElement;
const onHeaderChange = jest.fn().mockImplementation((element) => {
buttonElement = element;
});
render(<MyComponent onHeaderChange={onHeaderChange} />);
const { getByRole } = render(buttonElement);
expect(getByRole('button')).toHaveTextContent('Back');
});
我有一个组件接收一个函数作为 prop 并将渲染的元素传递给它,挂载:
function MyComponent(props) {
useEffect(() => {
props.onHeaderChange(<button>Back</button>)
}, [])
return (<div>My Component</div>)
}
我想编写一个测试来检查后退按钮是否通过:
test("it renders the back button", () => {
const onHeaderChange = jest.fn()
const { getByText } = render(
<MyComponent {...props} onHeaderChange={onHeaderChange} />
)
expect(onHeaderChange).toHaveBeenCalledWith("How to test for the back button here?")
})
但我不确定 jest / react 测试库语法是什么?
有两种解决方法:
选项 1. 将 JSX 传递给 toHaveBeenCalledWith
方法就足够了。为什么?因为 JSX 是 React.createElement()
方法的语法糖。使用 JSX 编写的代码将转换为使用 React.createElement()
。它的 return 值只是一个 JavaScript 对象。
index.tsx
:
import React, { useEffect } from 'react';
export function MyComponent(props) {
useEffect(() => {
props.onHeaderChange(<button>Back</button>);
}, []);
return <div>My Component</div>;
}
index.test.tsx
:
import { render } from '@testing-library/react';
import React from 'react';
import { MyComponent } from '.';
describe('71995270', () => {
test('it renders the back button', () => {
const onHeaderChange = jest.fn();
render(<MyComponent onHeaderChange={onHeaderChange} />);
const expectedElement = React.createElement('button', null, 'Back');
console.log('expectedElement: ', expectedElement);
expect(onHeaderChange).toHaveBeenCalledWith(expectedElement);
expect(onHeaderChange).toHaveBeenCalledWith(<button>Back</button>);
});
});
PASS Whosebug/71995270/index.test.tsx (14.782 s)
71995270
✓ it renders the back button (42 ms)
console.log
expectedElement: {
'$$typeof': Symbol(react.element),
type: 'button',
key: null,
ref: null,
props: { children: 'Back' },
_owner: null,
_store: {}
}
at Object.<anonymous> (Whosebug/71995270/index.test.tsx:11:13)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 16.871 s
选项 2. 使用 mockImplementation
模拟 onHeaderChange
函数并获取测试用例中的 button
元素,render
它并断言。
test('it renders the back button - 2', () => {
let buttonElement;
const onHeaderChange = jest.fn().mockImplementation((element) => {
buttonElement = element;
});
render(<MyComponent onHeaderChange={onHeaderChange} />);
const { getByRole } = render(buttonElement);
expect(getByRole('button')).toHaveTextContent('Back');
});