![](/img/trans.png)
[英]is there solve for this Error: Could not find “store” in the context of “Connect(App)”. Either wrap the root component in a <Provider>
[英]Could not find "store" in the context of "Connect(Items)". Either wrap the root component in a <Provider> in react.js?
我正在使用 React 測試庫編寫帶有計數器的簡單測試。 由於提到的與store有關的錯誤,我的測試失敗了。
我嘗試使用不同的方法來解決它,例如創建一個mockStore並將組件包裝在Shallow和Provider周圍。 我也嘗試在 index.js 中創建商店,但我已經導入了商店。我似乎無法指出問題所在。
如果有人能告訴我如何解決它,我將不勝感激。
這是我的代碼:
商店.js :
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'
import rootReducer from './reducers'
const initialState = {
}
const middleware = [thunk]
const store = createStore(rootReducer, initialState, composeWithDevTools(applyMiddleware(...middleware)))
export default store;
index.js:
import "./index.css";
import reportWebVitals from "./reportWebVitals";
import { Provider } from "react-redux";
import store from "./store/store";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<Provider store={store}>
<App />
</Provider>
</BrowserRouter>,
document.getElementById("root")
);
reportWebVitals();
比爾.test.js:
import { screen, fireEvent, act } from "@testing-library/react";
import BillList from "../BillList";
import Adapter from 'enzyme-adapter-react-16'
import configureMockStore from "redux-mock-store";
import { shallow, configure } from "enzyme";
import { Provider } from "react-redux";
const mockStore = configureMockStore();
const store = mockStore({});
configure({adapter: new Adapter()});
describe("<BillList />", () => {
// will display 1 by default because there will be already an item when the page renders
test("display counter text", () => {
shallow(
<Provider store={store}>
<BillList />
</Provider>
)
expect(screen.queryByTestId("counter-text")).toBe("1");
});
// Button increments the price value by +1
test("increment counter", () => {
shallow(
<Provider store={store}>
<BillList />
</Provider>
)
const btnIncrement = screen.queryByTestId("btn-increment");
fireEvent.click(btnIncrement);
expect(screen.queryByTestId("counter-text")).toBe("2");
});
// Button decrements the price value by -1
test("decrement counter", () => {
shallow(
<Provider store={store}>
<BillList />
</Provider>
)
const btnDecrement = screen.queryByTestId("btn-decrement");
fireEvent.click(btnDecrement);
expect(screen.queryByTestId("counter-text")).toHaveTextContent("1");
});
});
BillList.js:
import React, { useState } from "react";
import "./Bill.css";
import { Link, useParams, Switch, Route } from "react-router-dom";
import { connect,} from "react-redux";
import { getItems } from "../store/actions/itemsActions";
function BillList({ items }) {
const [counter, setCounter] = useState(1);
const { id } = useParams();
var ust = parseFloat(0.18);
function Display(props) {
return <label style={{ marginLeft: ".5rem" }}>{props.message}</label>;
}
return (
<div className="bills">
<div
className="main-title"
style={{
textAlign: "center",
justifyContent: "center",
alignItems: "center",
fontSize: 14,
}}
>
<h1>Bakery</h1>
<h1>Company Gbr</h1>
<h1>Oranienburger Straße 120</h1>
<h1>10119 Berlin</h1>
</div>
<div className="bills-container">
{/* pass in the details */}
<div className="item-list">
{items &&
items.items
.filter((item) => item.id === Number(id))
.map((item) => (
<React.Fragment key={item.id}>
<div className="bill-time">
<div className="bill">
<h4>
{" "}
<strong>Bill: </strong>
{item.billNumber}
</h4>
</div>
<div className="time">
<h4>
{" "}
<strong>Time: </strong>
{item.created_datetime}
</h4>
</div>
</div>
<div className="lines-time">
------------------------------------------------------------------------------------------
</div>
{/* Counter */}
<div className="price-total">
<div className="head-title">
<div className="title">
<h3>
{" "}
<strong>Title: {item.title} </strong>
</h3>
</div>
<div className="counter" data-testid="counter-text">
<strong>
<Display message={counter} />x
</strong>
</div>
<div className="lines">------------</div>
</div>
<div className="increase">
<button onClick={() => setCounter(counter + 1)} data-testid="btn-increment">+</button>
</div>
<div className="decrease">
<button onClick={() => setCounter(counter - 1)} data-testid="btn-decrement">-</button>
</div>
{/* Price and total */}
<div className="price">
<h4>
<strong>Price: {parseFloat(item.price).toFixed(2)}€ </strong>
</h4>
</div>
<div className="a">A</div>
<div className="total">
<h4>Total: </h4>
</div>
<div className="total-price">
{parseFloat(item.price * counter).toFixed(2)}€
</div>
<div className="given">
<h4>Given: (iZettle)</h4>
</div>
<div className="given-price">
{parseFloat(item.price * counter).toFixed(2)}€
</div>
<div className="lines-taxes">
-------------------------------------------------------------------------------
</div>
<div className="gross">
<h4>
<strong>gross</strong>
</h4>
</div>
<div className="gross-price">{((parseFloat(item.price) * counter)).toFixed(2)}€</div>
<div className="taxes">
<h4>USt.%</h4>
</div>
<div className="percent">A=7%</div>
<div className="ust">
<h4>USt.</h4>
</div>
<div className="ust-percent">{(ust * counter).toFixed(2)} €</div>
{/* net - the USt */}
<div className="net">
<h4>net</h4>
</div>
<div className="net-result">
{(parseFloat(item.price) * counter - parseFloat(0.18 * counter)).toFixed(2)} €
</div>
</div>
</React.Fragment>
))}
</div>
{/* Paragraph */}
<div className="terminal">
<p> Table: Counter</p>
<p> Terminal: Terminal 1</p>
</div>
<div className="TSE-Transaktion ">
<p>
TSE-Transaktion
</p>
<p>TSE-Signatur-Nr. </p>
<p>
TSE-Start
</p>
<p>
TSE-Stop
</p>
<p>
TSE-Seriennummer
</p>
<p>
TSE-Zeitformat
</p>
<p>
TSE-Signatur
</p>
<p>
TSE-Hashalgorithmus
</p>
<p>
TSE Status
</p>
</div>
<div className="right-side">
<p>
1831
</p>
<p>
98009
</p>
<p>
2020-04-21T09:29:38.00000Z
</p>
<p>
2020-04-21T09:29:50.00000Z
</p>
<p>
5f2897cc074ae841330658eadd324661159f53b7ffd29215
</p>
<p>
utcTime
</p>
<p>
bXkPffFOcetbFokYrOqr/7EYrAc0PH6r
</p>
<p>
ecdsa-plain-SHA256
</p>
<p>
In evaluation
</p>
</div>
<div className="de11">
<p>Ust-Id: DE11111111</p>
</div>
{/* Button */}
</div>
<div className="button-path">
<Link data-testid="analyse-receipt-path" to="/">
<div className="button">
<button data-testid="analyse-receipt" className="main-button">Analyse Receipt</button>
</div>
</Link>
</div>
<Switch>
<Route path="/bills/:id" />
</Switch>
</div>
);
}
const mapStateToProps = (state) => {
return {
items: state.items,
};
};
const mapDispatchToProps = (dispatch) => {
return {
getItems: () => dispatch(getItems()),
};
};
export default connect(mapStateToProps, mapDispatchToProps) (BillList);
您正在測試該組件,因此您無法訪問Provider
,因為它是父組件。 您可以創建自定義包裝器,以便在每個測試中使用 Redux。 使用下面的你將使用reduxRender
而不是標准render
import { render} from '@testing-library/react'
import { Provider as ReduxProvider } from 'react-redux'
import store from './whereverYourStoreIs/store'
/** To be used whenever Redux is referenced */
const ReduxWrapper = ({ children }) => (
<ReduxProvider store={store}>
{children}
</ReduxProvider>
)
/**Render used for Redux */
const reduxRender = (ui, options) =>
render(ui, { wrapper: ReduxWrapper, ...options })
試試 mocking react-redux。 導入后將其放在單元測試文件的頂部。
jest.mock('react-redux', () => ({
connect: () => (ReactComponent) => ReactComponent,
}));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.