编写单元测试以检查应用程序是否在 react-native 中离线
Writing a unit test to check if the app is offline in react-native
我有以下组件,如果应用程序处于离线状态,它会在应用程序上显示文本。
import React from 'react';
import { useNetInfo } from '@react-native-community/netinfo';
import { Label } from 'components/ui';
const OfflineNotice = () => {
const netInfo = useNetInfo();
if (netInfo.type !== 'unknown' && netInfo.isInternetReachable === false) {
return <Label size={18} text='No Internet Connection' />;
}
return null;
};
export default OfflineNotice;
我想为此编写一个单元测试以检查它是否正常工作。我怎样才能做到这一点?
我是单元测试的新手。我不明白如何嘲笑这个。
我使用 typescript 和 testing-library/react-native。
更新:
为什么第一次测试失败了?它不应该为空。但它失败了。错误是,
OfflineNotice component › test
expect(received).not.toBeNull()
Received: null
15 |
16 | const { queryByText } = render(<OfflineNotice />);
> 17 | expect(queryByText(/no internet connection/i)).not.toBeNull();
| ^
18 | });
19 |
at Object.<anonymous> (src/components/offline-notice/offline-notice.test.tsx:17:56)
浏览 react-native-netinfo
github 存储库,troubleshooting 部分
You should then add the following to your Jest setup file to mock the
NetInfo Native Module:
import mockRNCNetInfo from '@react-native-community/netinfo/jest/netinfo-mock.js';
jest.mock('@react-native-community/netinfo', () => mockRNCNetInfo);
他们的测试模拟是:
const defaultState = {
type: 'cellular',
isConnected: true,
isInternetReachable: true,
details: {
isConnectionExpensive: true,
cellularGeneration: '3g',
},
};
const RNCNetInfoMock = {
configure: jest.fn(),
fetch: jest.fn(),
addEventListener: jest.fn(),
useNetInfo: jest.fn(),
};
RNCNetInfoMock.useNetInfo.mockResolvedValue(defaultState);
鉴于此,我认为您可以在每个单元测试用例中制作您自己的模拟解析值:
import { useNetInfo } from '@react-native-community/netinfo';
jest.mock('@react-native-community/netinfo', () => {
useNetInfo: jest.fn(),
});
...
// Happy path test, known type and internet unreachable
useNetInfo.mockResolvedValueOnce({
type: 'test', // not 'unknown'
isInternetReachable: false,
});
// assert render non-null
const { queryByText } = render(<OfflineNotice />);
expect(queryByText(/no internet connection/i)).not.toBeNull();
...
// Sad path test, known type and internet reachable
useNetInfo.mockResolvedValueOnce({
type: 'test', // not 'unknown'
isInternetReachable: true,
});
// assert render null
const { queryByText } = render(<OfflineNotice />);
expect(queryByText(/no internet connection/i)).toBeNull();
...
// Sad path test, unknown type and internet unreachable
useNetInfo.mockResolvedValueOnce({
type: 'unknown',
isInternetReachable: false,
});
// assert render null
const { queryByText } = render(<OfflineNotice />);
expect(queryByText(/no internet connection/i)).toBeNull();
...
// Sad path test, unknown type and internet reachable
useNetInfo.mockResolvedValueOnce({
type: 'test', // not 'unknown'
isInternetReachable: true,
});
// assert render null
const { queryByText } = render(<OfflineNotice />);
expect(queryByText(/no internet connection/i)).toBeNull();
反应测试库
现在我的测试正常了。但它给出了意想不到的输出。
组件:
import React from 'react';
import { useNetInfo } from '@react-native-community/netinfo';
import { Label } from 'components/ui';
import strings from './offline-notice.strings';
import styles from './offline-notice.styles';
const OfflineNotice = ({ style, text }: IProps) => {
const netInfo = useNetInfo();
if (netInfo.type !== 'unknown' && netInfo.isInternetReachable === false) {
return <Label size={18} style={[styles.label, style]} text={text} />;
}
return null;
};
OfflineNotice.defaultProps = {
text: strings.NO_INTERNET_CONNECTION,
};
interface IProps {
style?: Object;
text?: string;
}
export default OfflineNotice;
测试:
import { render } from '@testing-library/react-native';
import React from 'react';
import { useNetInfo } from '@react-native-community/netinfo';
import OfflineNotice from './offline-notice.component';
import strings from './offline-notice.strings';
describe('OfflineNotice component', () => {
it('should display the message if internet is not reachable', () => {
useNetInfo.mockResolvedValueOnce({
type: 'test',
isInternetReachable: false,
});
const { getByText } = render(<OfflineNotice text={strings.NO_INTERNET_CONNECTION} />);
expect(getByText(strings.NO_INTERNET_CONNECTION)).not.toBeNull();
});
it('should not display the message if internet is reachable', () => {
useNetInfo.mockResolvedValueOnce({
type: 'test',
isInternetReachable: true,
});
const { getByText } = render(<OfflineNotice text={strings.NO_INTERNET_CONNECTION} />);
expect(getByText(strings.NO_INTERNET_CONNECTION)).toBeNull();
});
});
Jest.Setup.ts
import mockRNCNetInfo from '@react-native-community/netinfo/jest/netinfo-mock.js';
jest.mock('@react-native-community/netinfo', () => mockRNCNetInfo);
当运行测试时,给出如下输出。我在这里做错了什么?
正如@Drew 所说,我根据 documentation 设置了配置,但我在 mock 中做了一些不同的测试。
对我来说,我这样做并工作:
jest.mock('@react-native-community/netinfo', () => ({
...jest.requireActual('@react-native-community/netinfo'),
useNetInfo: () => ({
isConnected: true,
})
}));
我有以下组件,如果应用程序处于离线状态,它会在应用程序上显示文本。
import React from 'react';
import { useNetInfo } from '@react-native-community/netinfo';
import { Label } from 'components/ui';
const OfflineNotice = () => {
const netInfo = useNetInfo();
if (netInfo.type !== 'unknown' && netInfo.isInternetReachable === false) {
return <Label size={18} text='No Internet Connection' />;
}
return null;
};
export default OfflineNotice;
我想为此编写一个单元测试以检查它是否正常工作。我怎样才能做到这一点? 我是单元测试的新手。我不明白如何嘲笑这个。
我使用 typescript 和 testing-library/react-native。
更新: 为什么第一次测试失败了?它不应该为空。但它失败了。错误是,
OfflineNotice component › test
expect(received).not.toBeNull()
Received: null
15 |
16 | const { queryByText } = render(<OfflineNotice />);
> 17 | expect(queryByText(/no internet connection/i)).not.toBeNull();
| ^
18 | });
19 |
at Object.<anonymous> (src/components/offline-notice/offline-notice.test.tsx:17:56)
浏览 react-native-netinfo
github 存储库,troubleshooting 部分
You should then add the following to your Jest setup file to mock the NetInfo Native Module:
import mockRNCNetInfo from '@react-native-community/netinfo/jest/netinfo-mock.js'; jest.mock('@react-native-community/netinfo', () => mockRNCNetInfo);
他们的测试模拟是:
const defaultState = {
type: 'cellular',
isConnected: true,
isInternetReachable: true,
details: {
isConnectionExpensive: true,
cellularGeneration: '3g',
},
};
const RNCNetInfoMock = {
configure: jest.fn(),
fetch: jest.fn(),
addEventListener: jest.fn(),
useNetInfo: jest.fn(),
};
RNCNetInfoMock.useNetInfo.mockResolvedValue(defaultState);
鉴于此,我认为您可以在每个单元测试用例中制作您自己的模拟解析值:
import { useNetInfo } from '@react-native-community/netinfo';
jest.mock('@react-native-community/netinfo', () => {
useNetInfo: jest.fn(),
});
...
// Happy path test, known type and internet unreachable
useNetInfo.mockResolvedValueOnce({
type: 'test', // not 'unknown'
isInternetReachable: false,
});
// assert render non-null
const { queryByText } = render(<OfflineNotice />);
expect(queryByText(/no internet connection/i)).not.toBeNull();
...
// Sad path test, known type and internet reachable
useNetInfo.mockResolvedValueOnce({
type: 'test', // not 'unknown'
isInternetReachable: true,
});
// assert render null
const { queryByText } = render(<OfflineNotice />);
expect(queryByText(/no internet connection/i)).toBeNull();
...
// Sad path test, unknown type and internet unreachable
useNetInfo.mockResolvedValueOnce({
type: 'unknown',
isInternetReachable: false,
});
// assert render null
const { queryByText } = render(<OfflineNotice />);
expect(queryByText(/no internet connection/i)).toBeNull();
...
// Sad path test, unknown type and internet reachable
useNetInfo.mockResolvedValueOnce({
type: 'test', // not 'unknown'
isInternetReachable: true,
});
// assert render null
const { queryByText } = render(<OfflineNotice />);
expect(queryByText(/no internet connection/i)).toBeNull();
反应测试库
现在我的测试正常了。但它给出了意想不到的输出。
组件:
import React from 'react';
import { useNetInfo } from '@react-native-community/netinfo';
import { Label } from 'components/ui';
import strings from './offline-notice.strings';
import styles from './offline-notice.styles';
const OfflineNotice = ({ style, text }: IProps) => {
const netInfo = useNetInfo();
if (netInfo.type !== 'unknown' && netInfo.isInternetReachable === false) {
return <Label size={18} style={[styles.label, style]} text={text} />;
}
return null;
};
OfflineNotice.defaultProps = {
text: strings.NO_INTERNET_CONNECTION,
};
interface IProps {
style?: Object;
text?: string;
}
export default OfflineNotice;
测试:
import { render } from '@testing-library/react-native';
import React from 'react';
import { useNetInfo } from '@react-native-community/netinfo';
import OfflineNotice from './offline-notice.component';
import strings from './offline-notice.strings';
describe('OfflineNotice component', () => {
it('should display the message if internet is not reachable', () => {
useNetInfo.mockResolvedValueOnce({
type: 'test',
isInternetReachable: false,
});
const { getByText } = render(<OfflineNotice text={strings.NO_INTERNET_CONNECTION} />);
expect(getByText(strings.NO_INTERNET_CONNECTION)).not.toBeNull();
});
it('should not display the message if internet is reachable', () => {
useNetInfo.mockResolvedValueOnce({
type: 'test',
isInternetReachable: true,
});
const { getByText } = render(<OfflineNotice text={strings.NO_INTERNET_CONNECTION} />);
expect(getByText(strings.NO_INTERNET_CONNECTION)).toBeNull();
});
});
Jest.Setup.ts
import mockRNCNetInfo from '@react-native-community/netinfo/jest/netinfo-mock.js';
jest.mock('@react-native-community/netinfo', () => mockRNCNetInfo);
当运行测试时,给出如下输出。我在这里做错了什么?
正如@Drew 所说,我根据 documentation 设置了配置,但我在 mock 中做了一些不同的测试。
对我来说,我这样做并工作:
jest.mock('@react-native-community/netinfo', () => ({
...jest.requireActual('@react-native-community/netinfo'),
useNetInfo: () => ({
isConnected: true,
})
}));