我正在尝试使用React Router V3测试下面的场景。基于step prop,我设置了一些状态变量,然后渲染组件。然后根据传递给
const TestComponent = ({
languageData,
locale,
route: { step },
}) => {
const [showTiles, setShowTiles] = useState(true);
const [showAdsSearch, setShowAdsSearch] = useState(false);
const [showBasicSearch, setShowBasicSearch] = useState(false);
const [showSubmitterFields, setShowSubmitterFields] = useState(false);
const viewHome = () => {
setShowBasicSearch(false);
setShowSubmitterFields(false);
setShowAdsSearch(false);
setShowTiles(true);
};
const viewBasicSearch = () => {
setShowBasicSearch(true);
setShowSubmitterFields(false);
setShowAdsSearch(false);
setShowTiles(false);
};
const viewAdSearch = () => {
setShowBasicSearch(false);
setShowSubmitterFields(false);
setShowAdsSearch(true);
setShowTiles(false);
};
const viewCreateSubmitterProfileFields = () => {
setShowBasicSearch(false);
setShowSubmitterFields(true);
setShowAdsSearch(false);
setShowTiles(false);
};
const stepMap = new Map([
[1, viewHome],
[2, viewCreateSubmitterProfileFields],
[3, viewBasicSearch],
[4, viewAdSearch],
]);
useEffect(() => {
const currentState = stepMap.get(step) || viewHome;
currentState();
}, [step]);
if (Object.entries(languageData).length === 0) {
return <ProgressCircle />;
}
return (
<IntlProvider locale={locale} messages={languageData}>
<UserContext.Consumer>
{(user) => (Object.keys(user).length > 0 ? (
<HomeView
className={styles.grayBg}
showAdsSearch={showAdsSearch}
setShowAdsSearch={setShowAdsSearch}
showSubmitterFields={showSubmitterFields}
setShowSubmitterFields={setShowSubmitterFields}
showBasicSearch={showBasicSearch}
setShowBasicSearch={setShowBasicSearch}
showTiles={showTiles}
setShowTiles={setShowTiles}
/>
) : <div>NO USER CONTEXT SET IN ROOT MODULE</div>)}
</UserContext.Consumer>
</IntlProvider>
);
};
字符串
Home组件:
export function Home({
showTiles,
setShowTiles,
showBasicSearch,
setShowBasicSearch,
showAdsSearch,
setShowAdsSearch,
showSubmitterFields,
setShowSubmitterFields,
}) {
return (
<React.Fragment>
<HeaderSection
setShowBasicSearch={setShowBasicSearch}
showBasicSearch={showBasicSearch}
setShowTiles={setShowTiles}
setShowAdsSearch={setShowAdsSearch}
setSubmitterIdToView={setSubmitterIdToView}
setSubmitterName={setSubmitterName}
setShowSubmitterFields={setShowSubmitterFields}
/>
<div id="home" className={styles.grayBgForHome}>
{showTiles && (
<TilesView
setShowBasicSearch={setShowBasicSearch}
setShowTiles={setShowTiles}
setShowAdsSearch={setShowAdsSearch}
showAdsSearch={showAdsSearch}
showSubmitterFields={showSubmitterFields}
setShowSubmitterFields={setShowSubmitterFields}
/>
)}
{showBasicSearch && (
<React.Fragment>
<h1 className={styles.headingText}>
Search Submitter Profile
</h1>
<ConnectedBasicSearch/>
</React.Fragment>
)}
{showAdsSearch && (
<React.Fragment>
<h1 className={styles.headingText}>
Advanced Search Submitter Profile
</h1>
<ConnectedAdvancedSearch/>
</React.Fragment>
)}
{showSubmitterFields && (
<React.Fragment>
<h1 className={styles.headingText}>Create Submitter Profile</h1>
<ConnectedSubmitterProfile/>
</React.Fragment>
)}
</div>
<FooterSection />
</React.Fragment>
);
}
型
在我的测试中,我有下面的。我试图做的是用step = 1渲染Home,它应该显示Tiles组件。然后我点击#basicSearchTile,这是一个链接到/submitter-profile/basic-search,并希望检查显示的某些元素:
async function clickElement(container, selector) {
const user = userEvent.setup();
const element = container.querySelector(selector);
await user.click(element);
}
async function checkDisplayed(container, selector, shouldBeDisplayed) {
const element = container.querySelector(selector);
if (shouldBeDisplayed) {
expect(element).toBeInTheDocument();
} else {
expect(element).not.toBeInTheDocument();
}
}
const props1 = {
languageData: { intlKeyMock: 'intlValueMock' },
locale: 'localeMock',
route: { step: 1 },
};
const props2 = {
languageData: { intlKeyMock: 'intlValueMock' },
locale: 'localeMock',
route: { step: 2 },
};
const props3 = {
languageData: { intlKeyMock: 'intlValueMock' },
locale: 'localeMock',
route: { step: 3 },
};
const props4 = {
languageData: { intlKeyMock: 'intlValueMock' },
locale: 'localeMock',
route: { step: 4 },
};
describe('Navigation tests', () => {
it('invalid submitterId on save for edit profile', async () => {
const { container } = render(
<Router initialEntries={['/submitter-profile']} history={createMemoryHistory()}>
<UserContext.Provider value={loggedInUser}>
<Route path="/" element={<TestableAxpSubmissionsWebSearchSubmitterProfile {...props1} />} />
<Route path="/submitter-profile" element={<TestableAxpSubmissionsWebSearchSubmitterProfile {...props1} />} />
<Route path="/submitter-profile/basic-search" element={<TestableAxpSubmissionsWebSearchSubmitterProfile {...props3} />} />
<Route path="/submitter-profile/create" element={<TestableAxpSubmissionsWebSearchSubmitterProfile {...props2} />} />
<Route path="/submitter-profile/advanced-search" element={<TestableAxpSubmissionsWebSearchSubmitterProfile {...props4} />} />
</UserContext.Provider>
</Router>
);
screen.debug();
await clickElement(container, '#basicSearchTile');
await clickElement(container, '#search-button');
await clickElement(container, '#resultTableRowsubmitterId123');
await clickElement(container, '#editToggle');
await clickElement(container, '#saveButton');
screen.debug();
await checkDisplayed(container, '#responseModalMsg', true);
await checkTextValue(container, '#responseModal', 'Must enter a valid value for Submitter ID.');
await clickElement(container, '#responseModal');
await checkDisplayed(container, '#responseModalMsg', false);
});
});
型
但是,每当我使用render时,screen.debug()调用都返回一个空的主体。
<body>
<div />
</body>
型
我也添加了路由定义的情况下,他们是有帮助的。路由在应用程序是伟大的工作。这只是测试,我不能得到工作
const Routes = [
<Route
key="submitter-profile-route"
path="/submitter-profile"
moduleName="axp-submissions-web-search-submitter-profile"
step={1}
/>,
<Route
key="create-submitter-profile-route"
path="/submitter-profile/create"
moduleName="axp-submissions-web-search-submitter-profile"
step={2}
/>,
<Route
key="basic-search-submitter-profile-route"
path="/submitter-profile/basic-search"
moduleName="axp-submissions-web-search-submitter-profile"
step={3}
/>,
<Route
key="advanced-search-submitter-profile-route"
path="/submitter-profile/advanced-search"
moduleName="axp-submissions-web-search-submitter-profile"
step={4}
/>];
型
解决方案:我能够使用Drews的答案来嘲笑我的路由器,就像这样
const TestHomeComponent = () => <UserContext.Provider value={loggedInUser}><TestableAxpSubmissionsWebSearchSubmitterProfile {...props1} /></UserContext.Provider>;
const TestBasicSearchComponent = () => <UserContext.Provider value={loggedInUser}><TestableAxpSubmissionsWebSearchSubmitterProfile {...props3} /></UserContext.Provider>;
const TestCreateComponent = () => <UserContext.Provider value={loggedInUser}><TestableAxpSubmissionsWebSearchSubmitterProfile {...props2} /></UserContext.Provider>;
const TestAdvSearchComponent = () => <UserContext.Provider value={loggedInUser}><TestableAxpSubmissionsWebSearchSubmitterProfile {...props4} /></UserContext.Provider>;
const { container, debug } = render(
<Router initialEntries={['/submitter-profile']} history={createMemoryHistory()}>
<UserContext.Provider value={loggedInUser}>
<Route path="/submitter-profile" component={TestHomeComponent} />
<Route path="/submitter-profile/basic-search" component={TestBasicSearchComponent} />
<Route path="/submitter-profile/create" component={TestCreateComponent} />
<Route path="/submitter-profile/advanced-search" component={TestAdvSearchComponent} />
<Route path="/" component={TestHomeComponent} />
</UserContext.Provider>
</Router>
);
型
2条答案
按热度按时间rqdpfwrv1#
React-Router v3 Route组件没有
element
prop,它有一个component
prop。更新测试代码以使用component
prop,并传递一个引用到组件而不是JSX。请确保以路径特异性的相反顺序指定路由,例如在 * 较少 * 特定路径之前呈现 * 更多 * 特定路径。
范例:
字符串
hs1ihplo2#
我已经添加了路由定义,以防它们有帮助。应用程序中的路由工作得很好。只是我无法进行测试。
首先,它似乎设置正确。但在您的测试中,您使用
@testing-library/react
中的render
来渲染组件,但这不支持react-router v3。我只是在想,你需要一个Router组件来在测试中导航。
我在这里使用
history
中的createMemoryHistory
,因为我们需要先创建一个历史对象,然后将其传递给Router
。如果找不到
createMemoryHistory
或没有history
,通过执行npm install --save history
安装它。然后,创建一个路由器,如下面的示例,以允许您在测试中模拟导航。字符串