2

I have the following React Component:

import { getSeasonsalCode } from "./DiscountCodes.js";
import React, { Component } from "react";
import Rating from "./Rating.js";
import ReactDOM from "react-dom";
import "regenerator-runtime/runtime";

class Product extends Component {
  constructor(props) {
    super(props);
    this.handleEvent = this.handleEvent.bind(this);

    this.state = {
      name: "",
      rating: 0,
    };
  }

  setStarCount = (ct) => {
    this.setState({ rating: ct });
  };

  render() {
    var discount = getSeasonsalCode();
    return (
      <div>
        <span>{discount}</span>
        <Rating
          name="star_rating"
          size="2x"
          setStarCount={this.setStarCount}
        ></Rating>
      </div>
    );
  }
}

export default connect(mapStateToProps, null)(Product);

And the following product.test.js. It tests the Rating child component, which requires a callback function from the parent component to set the rating value:

import Rating from "../src/Rating.js";
import Product from "../src/Product.js";
import { shallow, mount } from "enzyme";
import expect from "expect";
import React from "react";
import { Provider } from "react-redux";
import { connect } from "react-redux";
import rootReducer from "../src/reducers/RootReducer.js";
import { createStore } from "redux";

describe("Product test suite", () => {
  it("set rating", () => {
    const store = createStore(
      rootReducer,
      window.__REDUX_DEVTOOLS_EXTENSION__ &&
        window.__REDUX_DEVTOOLS_EXTENSION__()
    );

    const rf_wrapper = mount(
      <Provider store={store}>
        <Product />
      </Provider>
    ).dive();
    const rf_instance = rf_wrapper.instance();
    const sr_wrapper = shallow(
      <Rating
        name="star_rating"
        size="2x"
        setStarCount={rf_instance.setStarCount()}
      />
    );

    sr_wrapper.find("#star4").simulate("click");
    expect(rf_wrapper.state("starcount")).toEqual(4);
  });
});

When I run the test, I get a TypeError saying discount is null or undefined at this line:

<span>{discount}</span>

What is causing this issue?

6
  • What's getSeasonsalCode? Commented Oct 12, 2021 at 1:30
  • Why aren't you unit testing the Rating component alone as a unit? What is `getSeasonsalCode`` doing during the test execution? Commented Oct 12, 2021 at 2:59
  • Fixed the typo. getSeasonsalCode is the external method imported at the top. I do have a separate test suite for Rating alone. Here I want to test both parent and child as there is a callback func (setStarCount) that I want to test. Commented Oct 12, 2021 at 12:21
  • Ah, I see now, then you might not want to additionally render a separate Rating component in your test, find the one rendered in rf_wrapper to interact with. What is getSeasonsalCode supposed to be doing to set discount? Is discount being used somewhere else that requires it to not be null or undefined? React is perfectly capable of rendering either of these values. Commented Oct 12, 2021 at 15:09
  • Finding the Rating component rendered in rf_wrapper makes sense, but unfortunatelty the null error is thrown when Product component is being mounted, so I can't even access the instance. getSeasonsalCode returns a discount code base on consumer loyalty points, seasonality, etc. The only thing product component does with the discount code is display it. Commented Oct 13, 2021 at 0:00

1 Answer 1

1

Had to make a few changes to my original test suite and this is what worked for me:

import * as disc_module from '../src/DiscountCodes.js'

describe("Product test suite", () => {
  it("set rating", () => {
    const store = createStore(
      rootReducer,
      window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    );
    
    var disc_mock_obj = {
        "discount":{
            "expiration": new Date()
            "code": "OAABYT"
        }}

    jest
    .spyOn(disc_module, 'getSeasonsalCode')
    .mockImplementation(() => disc_mock_obj);

    //Got rid of call to dive() since it was not needed
    const rf_wrapper = mount( <Provider store={store}><Product></Product></Provider>);
    const prod_inst = rf_wrapper.find('Product');
    
    //Find clickable child component of Rating by id or any other unique attribute
    const child = rf_wrapper.find({'#star2'})   
    child.simulate('click')     
    expect(prod_inst.state('starcount')).toEqual(2);
  });
});
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.