在 React Native 中测试 onLayout
Testing onLayout in React Native
我正在尝试使用 @testing-library/react-native 测试使用 onLayout 事件的组件,该组件通过组件道具使用 setState 函数,但从未调用该函数:
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: 100
Number of calls: 0
我怎样才能完成这项工作?怎么了?
组件:
type Props = {
children: React.ReactNode
setHeaderHeight: React.Dispatch<React.SetStateAction<number>>
}
const HeaderSetHeightWrapper = ({ children, setHeaderHeight }: Props) => {
return (
<Wrapper
onLayout={({
nativeEvent: {
layout: { height }
}
}) => {
setHeaderHeight(Math.floor(height))
}}
testID="header-h"
>
{children}
</Wrapper>
)
}
const Wrapper = styled.View`
position: absolute;
left: 0;
top: 0;
`
测试:
it('should set the header height on layout', async () => {
const mockHeight = 100
const setHeaderHeight = jest.fn()
const { getByTestId } = render(
<HeaderSetHeightWrapper setHeaderHeight={setHeaderHeight}>
<View style={{ width: 100, height: mockHeight }} />
</HeaderSetHeightWrapper>
)
const wrapper = getByTestId('header-h')
fireEvent(wrapper, new NativeTestEvent('onLayout', { nativeEvent: { layout: { height: mockHeight } } }))
await wait(() => expect(setHeaderHeight).toHaveBeenCalledWith(mockHeight))
})
wrapper.find('Wrapper').simulate('layout')
@testing-library/react-native
现在有一个 fireEvent.layout
触发器,至少从 v5.0.3 开始:
import { render, act, fireEvent } from '@testing-library/react-native';
test(() => {
const { getByTestId } = render(<MyComponent />);
const view = getByTestId('my-view');
act(() => {
fireEvent.layout(view, {
nativeEvent: {
layout: {
width: 300,
// etc
},
},
});
});
});
这应该会触发 onLayout
事件处理程序。
以后有需要的可以用fireEvent(element, eventName, data)
,它的文档是here,它的类型是:
type FireEventFunction = (
element: ReactTestInstance,
eventName: string,
...data: Array<any>
) => any;
因此,要触发 onLayout
,请使用 layout
事件名称:
// You can use any getBy* or another selector that returns a ReactTestInstance
fireEvent(getByText('Some label'), 'layout', {
nativeEvent: { layout: { height: 100 } }, // The event data you need
});
我正在尝试使用 @testing-library/react-native 测试使用 onLayout 事件的组件,该组件通过组件道具使用 setState 函数,但从未调用该函数:
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: 100
Number of calls: 0
我怎样才能完成这项工作?怎么了?
组件:
type Props = {
children: React.ReactNode
setHeaderHeight: React.Dispatch<React.SetStateAction<number>>
}
const HeaderSetHeightWrapper = ({ children, setHeaderHeight }: Props) => {
return (
<Wrapper
onLayout={({
nativeEvent: {
layout: { height }
}
}) => {
setHeaderHeight(Math.floor(height))
}}
testID="header-h"
>
{children}
</Wrapper>
)
}
const Wrapper = styled.View`
position: absolute;
left: 0;
top: 0;
`
测试:
it('should set the header height on layout', async () => {
const mockHeight = 100
const setHeaderHeight = jest.fn()
const { getByTestId } = render(
<HeaderSetHeightWrapper setHeaderHeight={setHeaderHeight}>
<View style={{ width: 100, height: mockHeight }} />
</HeaderSetHeightWrapper>
)
const wrapper = getByTestId('header-h')
fireEvent(wrapper, new NativeTestEvent('onLayout', { nativeEvent: { layout: { height: mockHeight } } }))
await wait(() => expect(setHeaderHeight).toHaveBeenCalledWith(mockHeight))
})
wrapper.find('Wrapper').simulate('layout')
@testing-library/react-native
现在有一个 fireEvent.layout
触发器,至少从 v5.0.3 开始:
import { render, act, fireEvent } from '@testing-library/react-native';
test(() => {
const { getByTestId } = render(<MyComponent />);
const view = getByTestId('my-view');
act(() => {
fireEvent.layout(view, {
nativeEvent: {
layout: {
width: 300,
// etc
},
},
});
});
});
这应该会触发 onLayout
事件处理程序。
以后有需要的可以用fireEvent(element, eventName, data)
,它的文档是here,它的类型是:
type FireEventFunction = (
element: ReactTestInstance,
eventName: string,
...data: Array<any>
) => any;
因此,要触发 onLayout
,请使用 layout
事件名称:
// You can use any getBy* or another selector that returns a ReactTestInstance
fireEvent(getByText('Some label'), 'layout', {
nativeEvent: { layout: { height: 100 } }, // The event data you need
});