簡體   English   中英

在“Connect(Items)”的上下文中找不到“store”。 要么將根組件包裝在<provider>在 react.js 中?</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並將組件包裝在ShallowProvider周圍。 我也嘗試在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM