在进行相同测试几个小时后,我感到沮丧。我有一个查询组件,它返回一个datatable
。该组件我已经对其进行了测试,并且具有100%的测试覆盖率。
该测试声称缺少第42、145、148、151行的覆盖范围(请参阅下面的组件以查看有关这些行的注释)。
如果您一直查看到该组件的末尾,它就会声称覆盖了某些操作处理程序。
但是现在我正在测试其父组件:
// imports
const GetShipments = ({
t,
shipmentsPaginationHandler,
toggleFiltersModalHandler,
isFiltersModalOpened,
}) => {
const removeFilterConst = filterKey => () => {
removeFilterHandler(filterKey);
};
return (
<>
<TableToolbarComp
toggleFiltersModal={toggleFiltersModalHandler} // LINE 42
isFiltersModalOpened={isFiltersModalOpened}
removeFilter={removeFilterConst}
/>
<Query
query={GET_SHIPMENTS}
variables={{
...filters,
shippedDate: filters.shippedDate,
limit: pagination.pageSize,
offset: (pagination.page - 1) * pagination.pageSize,
}}
context={{ uri: `/this?url=${softlayerAccountId}` }}
>
{({ loading, error, data }) => {
let tableRowsModel;
let itemsCount;
if (error) {
return (...);
}
if (loading) return (...);
if (data && data.GetShipments) {
({ itemsCount } = data.GetShipments);
if (data.GetShipments.shipments) {
tableRowsModel = data.GetShipments.shipments.map(row => ({
...row,
id: `${row.id}`,
type: row.type.name : '',
status: row.status ? row.status.name : '',
}));
} else {
tableRowsModel = [];
}
setCSVDataHandler(data.GetShipments);
}
return (
<ShipmentsTable tableRows={tableRowsModel} />
);
}}
</Query>
</>
);
};
GetShipments.propTypes = {
// propTypes validation
};
export default compose(
connect(
store => ({
softlayerAccountId: store.global.softlayerAccountId,
isFiltersModalOpened: store.shipments.filtersModalOpened,
}),
dispatch => ({
removeFilterHandler: filterKey => {
dispatch(removeFilter(filterKey));
},
toggleFiltersModalHandler: () => {
dispatch(toggleFiltersModal()); // LINE 145
},
}),
),
translate(),
)(GetShipments);
我创建的大多数测试似乎只是忽略了我在做什么。
这是我到目前为止所拥有的:
import React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { mount } from 'enzyme';
import { Provider as ReduxProvider } from 'react-redux';
import GetShipments from '../../containers/GetShipments';
import createMockStore from '../../../../utils/createMockStore';
import store from '../../../../redux/store';
import mocks from '../../__fixtures__/shipments-mock';
jest.mock('react-i18next', () => ({
// this mock makes sure any components using the translate HoC receive the t function as a prop
translate: () => Component => {
Component.defaultProps = { ...Component.defaultProps, t: key => key };
return Component;
},
}));
describe('Container to test: GetShipments', () => {
let props;
beforeEach(() => {
props = {
t: jest.fn(() => k => k),
softlayerAccountId: 123,
isFiltersModalOpened: false,
toggleFiltersModalHandler: jest.fn(() => k => k),
setFiltersHandler: jest.fn(() => k => k),
removeFilterHandler: jest.fn(() => k => k),
};
});
it('should render without errors', () => {
mount(
<MockedProvider
mocks={mocks.filter(mock => mock.id === 'get-shipments-default')}
>
<ReduxProvider store={store}>
<GetShipments
{...props}
store={createMockStore({
global: {
accountGuid: 'abcd-1234',
softlayerAccountId: '1234',
},
})}
/>
</ReduxProvider>
</MockedProvider>,
);
});
it('should render loading state initially', () => {
const wrapper = mount(
<MockedProvider mocks={[]} addTypename={false}>
<ReduxProvider store={store}>
<GetShipments {...props} />
</ReduxProvider>
</MockedProvider>,
);
expect(wrapper.find('DataTableSkeleton')).toHaveLength(1);
});
it('should render data', async () => {
const wrapper = mount(
<MockedProvider mocks={mocks} addTypename={false}>
<ReduxProvider store={store}>
<GetShipments store={store} {...props} />
</ReduxProvider>
</MockedProvider>,
);
await new Promise(resolve => setTimeout(resolve));
await wrapper.update();
console.log(wrapper.debug());
});
it('should NOT render any data', () => {
mount(
<MockedProvider mocks={[]} addTypename={false}>
<GetShipments store={store} />
</MockedProvider>,
);
});
});
那我想念什么?
答案 0 :(得分:0)
首先,您似乎在许多测试中都缺少断言。这是有目的的吗?例如,我希望您在第一个测试用例中使用快照断言(“它应呈现无错误”)。唯一可以断言的测试用例是“应该呈现加载状态”。
关于缺少的覆盖范围,而没有看到完整的Jest测试报告,我只是假设您突出显示的功能从未运行过,即您未测试dispatch(toggleFiltersModal())
在运行时执行toggleFiltersModalHandler
。为了达到100%的测试覆盖率,您需要测试这些功能。当您使用酶时,这可能很简单:
const wrapper = mount(
<MockedProvider mocks={mocks} addTypename={false}>
<ReduxProvider store={store}>
<GetShipments store={store} {...props} />
</ReduxProvider>
</MockedProvider>
);
wrapper.props().toggleFiltersModalHandler();
不幸的是,在使用HOC时,您很可能必须先find
组件,然后才能在prop上执行功能,如下所示:
const wrapper = mount(
<MockedProvider mocks={mocks} addTypename={false}>
<ReduxProvider store={store}>
<GetShipments store={store} {...props} />
</ReduxProvider>
</MockedProvider>
);
wrapper.find(GetShipments).props().toggleFiltersModalHandler();
毫无疑问,您必须做一些试验和错误才能在包装器中找到该道具,但是一旦找到它,只需执行它并断言该函数已经使用了一个开玩笑的间谍来执行。