У меня есть чистое приложение React-Redux, и оно работает как положено.
Приложение . js
import React, { useEffect } from "react";
import { useDispatch } from "react-redux";
import { Router, Route, Switch, Redirect } from "react-router-dom";
import history from "../history";
import LandingPage from "./home/LandingPage";
import { displayModules } from "../actions";
import Cart from "./home/Cart";
const App = () => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(displayModules());
}, [dispatch]);
return (
<Router history={history}>
<Switch>
<Route path="/" exact component={LandingPage}></Route>
<Route path="/cart" exact component={Cart}></Route>
<Route render={() => <Redirect to="/" />} />
</Switch>
</Router>
);
};
export default App;
LandingPage имеет вложенный компонент с именем Tile.
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import Tile from "../common/Tile";
import { addItemToCart, displayCartContents } from "../../actions";
import "./LandingPage.css";
const LandingPage = () => {
const modules = useSelector(state => state.data.modules);
const cart = useSelector(state => state.data.cart);
const dispatch = useDispatch();
const addToCart = item => {
dispatch(addItemToCart(item));
};
return (
<div className="app">
<div className="header">
<div className="text">Insurance modules</div>
<i
className="shopping cart icon"
onClick={() => {
dispatch(displayCartContents());
}}
>
<span className="badge">{cart.length}</span>
</i>
</div>
<div className="body">
{modules.map(module => (
<Tile key={module.id} module={module} addToCart={addToCart}></Tile>
))}
</div>
</div>
);
};
export default LandingPage;
Tile. js имеет кнопку, которую я хочу проверить.
import React, { useState } from "react";
import "./Tile.css";
const Tile = props => {
const { module, addToCart } = props;
const [coverage, setCoverage] = useState(parseInt(module.coverageMax - module.coverageMin) / 2);
const [price, setPrice] = useState((coverage * module.risk) / 100);
return (
<div className="tile">
<div className="tile-description">
<div>
<i className={`${module.icon} icon`}></i>
</div>
<div className="tile-name">{module.name}</div>
<div className="tile-risk">Risk(%): {module.risk}</div>
</div>
<div className="tile-footer">
<div className="tile-range">
<div className="field-label">
Select Coverage: <span className="coverage-display">{coverage}</span>
</div>
<div className="slidecontainer">
<span className="slider-step">{module.coverageMin}</span>
<input
type="range"
min={module.coverageMin}
max={module.coverageMax}
value={coverage}
className="slider"
onChange={e => {
setCoverage(e.target.value);
setPrice((e.target.value * module.risk) / 100);
}}
></input>
<span className="slider-step">{module.coverageMax}</span>
</div>
</div>
<div>
PRICE at this Coverage:<span className="tile-price">{price}</span>
</div>
<button
className="tile-button"
onClick={() => {
addToCart({
id: module.id,
name: module.name,
coverage: coverage,
price: price,
timeStamp: Math.ceil(new Date().getTime() * Math.random() * Math.random())
});
}}
>
Add module to cart
</button>
</div>
</div>
);
};
export default Tile;
App.test. js работает нормально, и я могу найти вложенную страницу Landing div по className prop.
import React from "react";
import configureStore from "redux-mock-store";
import { Provider } from "react-redux";
import renderer from "react-test-renderer";
import App from "../components/App";
import history from "../history";
import { displayModules } from "../actions";
import { DISPLAY_MODULES } from "../actions/types";
const mockStore = configureStore([]);
describe("App Component test", () => {
let store = {};
let wrappedComponent = {};
const expectedActions = {
type: DISPLAY_MODULES,
payload: [
{
id: 0,
icon: "bicycle",
name: "Bike",
coverageMin: 0,
coverageMax: 3000,
risk: 30
},
{
id: 1,
icon: "gem",
name: "Jewelry",
coverageMin: 500,
coverageMax: 10000,
risk: 5
},
{
id: 2,
icon: "microchip",
name: "Electronics",
coverageMin: 500,
coverageMax: 6000,
risk: 35
},
{
id: 3,
icon: "football ball",
name: "Sports Equipment",
coverageMin: 0,
coverageMax: 20000,
risk: 30
}
]
};
beforeEach(() => {
store = mockStore({
data: {
modules: [],
cart: [],
total: 0
}
});
store.dispatch = jest.fn(displayModules);
wrappedComponent = renderer.create(
<Provider store={store}>
<App />
</Provider>
);
});
it("should render with given state from Redux store", () => {
expect(wrappedComponent.toJSON()).toMatchSnapshot();
});
it("should have an app from Landing Page", () => {
expect(wrappedComponent.root.findByProps({ className: "app" })).toBeDefined();
});
it("should show landing page for default route", () => {
*debugger;
expect(wrappedComponent.root.findByProps({ className: "shopping cart icon" })).toBeDefined();*
});
it("should show cart page for /cart route", () => {
history.push("/cart");
expect(wrappedComponent.root.findByProps({ className: "backward icon" })).toBeDefined();
});
it("should redirect to landing page for unmatched 404 routes", () => {
history.push("/someRandomRoute");
expect(wrappedComponent.root.findByProps({ className: "shopping cart icon" })).toBeDefined();
});
it("should dispatch displayModules action on app mount", async () => {
const actualAction = await store.dispatch();
expect(actualAction).toEqual(expectedActions);
});
});
Но если вы видите тестовый отладчик
Дети div с className: body не имеет детей. Вот почему он не может найти компонент Tile. Можете ли вы подсказать, почему дети не нужны для тела? Я видел это раньше, даже я пытался с ферментом, я столкнулся с этой проблемой. Поскольку это компонент Redux, я не могу напрямую создать целевую страницу или компонент Tile для тестирования. Как проверить вложенные элементы?