【发布时间】:2021-10-28 18:49:56
【问题描述】:
我正在使用 React 测试库编写带有计数器的简单测试。由于提到的与 store 有关的错误,我的测试失败了。
我尝试使用不同的方法来解决它,例如创建 mockStore 并将组件包裹在 Shallow 和 Provider 周围。我也尝试在 index.js 中创建商店,但我已经导入了 store。我似乎无法指出问题所在。
如果有人能告诉我如何解决它,我将不胜感激。
这是我的代码:
Store.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();
Bill.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);
【问题讨论】:
-
你遇到了什么错误?你正在测试
BillList组件,显示代码 -
我收到此错误在“Connect(Items)”的上下文中找不到“store”。要么将根组件包装在
** 中,我知道这是因为商店,但我已经将 ** 组件包装在中。 ..我有点困惑,一切似乎都到位了,我更新了代码,请检查一下! -
错误提到了
Connect(Items),但我在任何地方都没有看到Items组件。你有这样的组件。另外,当你只使用 BillList 组件(非连接版本)时,它工作正常吗?
标签: javascript reactjs redux react-redux react-testing-library