Uncaught [Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>]

  javascript, reactjs, unit-testing

I’m using React Redux and am trying to test a functional component I wrote. I just want to test to make sure the button works (by sending a click event) and the button text is as expected. My error message is the title and here is my test class

import { AddBudgetForm } from "../features/Budget/AddBudgetForm";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";


let container:HTMLElement = document.createElement("div");
beforeEach(() => {
  // setup a DOM element as a render target
  document.body.appendChild(container);
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
});

it("changes value when clicked", () => {
    const onChange = jest.fn();
    act(() => {
      render(<AddBudgetForm />, container);
    });

  // get ahold of the button element, and trigger some clicks on it
  const button = document.querySelector("[data-testid=click]");
  if(button){
      expect(button.innerHTML).toBe("Create Budget");

      act(() => {
        button.dispatchEvent(new MouseEvent("click"));
      });

      expect(onclick).toHaveBeenCalledTimes(1);
  }
})

I was following along with this set of documentation

https://reactjs.org/docs/testing-recipes.html

I have tried some other solutions like adding a wrapper to my test

const wrapper = mount(
    <Provider store = {store}>
        <AddBudgetForm  />
    </Provider>
);

But then got errors about setting up with Enzyme, which i’m not opposed to, but I want to understand exactly what is going on, not just copy paste code. My understanding of why my test won’t work is because the component I’m trying to test is not wrapped in a Provider component (although it is in my index.js) and I don’t understand how to wrap my component and then test it.

Here is my AddBudgetForm component

import { useState } from 'react'
import { budgetAdded } from './BudgetsSlice'
import { useDispatch } from 'react-redux'
import { Link } from 'react-router-dom'


export const AddBudgetForm = () => {
    const [carPayment, setCarPayment] = useState('')
    const [housePayment, setHousePayment] = useState('')
    const [bills, setBills] = useState('')
    const [studentLoans, setStudentLoans] = useState('')
    const [monthlyPay, setMonthlyPay] = useState('')
    const [savings, setSavings] = useState('')
    const [leftOver, setLeftOver] = useState('')

    const dispatch = useDispatch()

    const onCarPaymentChange = e => setCarPayment(e.target.value)
    const onHousePaymentChange = e => setHousePayment(e.target.value)
    const onBillPaymentChange = e => setBills(e.target.value)
    const onStudentLoanPaymentChange = e => setStudentLoans(e.target.value)
    const onMonthlyPayChange = e => setMonthlyPay(e.target.value)
    const onSavingsChange = e => setSavings(e.target.value)

    const onSavePostClicked = () => {

        if (carPayment && housePayment && bills && studentLoans && monthlyPay && savings){
            dispatch(budgetAdded(carPayment, housePayment, bills, studentLoans, monthlyPay, savings, leftOver))
            setCarPayment('')
            setHousePayment('')
            setBills('')
            setStudentLoans('')
            setMonthlyPay('')
            setSavings('')
        }
    }

    return (
    <form>
        <div>
            <h2>Create your budget!</h2>
            <div className="form-group">
                <label>Car Payment</label>
                <input 
                    className="form-control"
                    placeholder="Please enter your car payment"
                    type="number"
                    id="carPayment"
                    name="carPayment"
                    value={carPayment}
                    onChange={onCarPaymentChange}
                    />
            </div>
            <div className="form-group">
                <label>House Payment</label>
                <input 
                    className="form-control"
                    placeholder="Please enter your house payment"
                    type="number"
                    id="housePayment"
                    name="housePayment"
                    value={housePayment}
                    onChange={onHousePaymentChange}
                />
            </div>
            <div className="form-group">
                <label>Bills</label>
                <input 
                    className="form-control"
                    placeholder="Please enter the total of all your other bills"
                    type="number"
                    id="bills"
                    name="bills"
                    value={bills}
                    onChange={onBillPaymentChange}
                />
            </div>
            <div className="form-group">
                <label>Student Loans</label>
                <input 
                    className="form-control"
                    placeholder="Please enter your student loans"
                    type="number"
                    id="studentLoans"
                    name="studentLoans"
                    value={studentLoans}
                    onChange={onStudentLoanPaymentChange}
                />
            </div>
            <div className="form-group">
                <label>Monthly Pay</label>
                <input 
                    className="form-control"
                    placeholder="Please enter the amount you get paid monthly"
                    type="number"
                    id="monthlyPay"
                    name="monthlyPay"
                    value={monthlyPay}
                    onChange={onMonthlyPayChange}
                />
            </div>
            <div className="form-group">
                <label>Savings</label>
                <input 
                    className="form-control"
                    placeholder="Please enter your savings"
                    type="number"
                    id="studentLoans"
                    name="studentLoans"
                    value={savings}
                    onChange={onSavingsChange}
                />
            </div>
                <Link to={`/Collateral/AddCollateralForm`}>
                    <button onClick={onSavePostClicked} type="button" className="btn btn-primary" data-testid="click">
                        Create Budget
                    </button>
                </Link>
        </div>
    </form>
    )
}

Source: Ask Javascript Questions

LEAVE A COMMENT