Can't get refs to work when using domjs, as tested with react testing library
Asked Answered
T

0

6

this is a question about using React refs inside of specs. specifically, I am seeing different behavior in my browser from what I see when run in the test.

// app_container.test.js

import React from 'react'
import ReactDOM from 'react-dom'
import AppContainer from "./app_container"
import { render, fireEvent, waitForElement, cleanup, wait } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import axiosMock from 'axios'

import { useAsync } from "react-use"

afterEach(cleanup);

test("renders", () => {
  const { getByTestId } = render(<AppContainer />);
  expect(getByTestId("app-container")).toHaveClass("app-container");

});


test("when mounted, it loads the rings", async () => {
  jest.setTimeout(15000);

  const { getByTestId } = render(<AppContainer />);

  const container = getByTestId('app-container')

  await wait(() => expect(getByText("Abc")).toBeInTheDocument());

})

// app_container.js code

import React from 'react'

import Ring from "./ring";
import LogoContainer from './logo_container'

const rings_data = [
  { key: 2,
    name: "Abc",
    blurb: "Lorem ipsum."
  }
]



class AppContainer extends React.Component {
  state = {
    ringsLoaded: false,
  }
  constructor(props) {
    super()
    this.abc_logo_inner_ref = React.createRef()
    this.rings = []
  }

  componentDidMount() {
    setTimeout(() => {
      console.log("the timeout has invoked the function ")
      this.rings = rings_data

      console.log("this.abc_logo_inner_ref.current= ", this.abc_logo_inner_ref)

      // expecting the ref to be populated with {current: (html object)}  but instead it is
      // {current: null}

      },1000)

  }

  render () {
    const effect = this.effect
    return (
      <div data-testid="app-container" style={{height: "100vh"}}
           className="app-container">
          <LogoContainer  ref={this.abc_logo_inner_ref}

          />
          {ringsLoaded ?
          <div>
            {this.rings.map((ele, i) =>
              <Ring
                ref={this.marbles_refs_array[i]}
              />)
            }
          </div>
          : ''}
      </div>
    )
  }
}

export default AppContainer

What is happening is that this code works for me fine in the browser. When the function is invoked in setTimeout, this.abc_logo_inner_ref is correctly attached to the DOM element created by LogoContainer

I can inspect it (while in my browser using debugger) and it looks like so:

correct output for React ref

However, when run from my Jest spec (above), the ref is not populated, even though I am rendering the component in the test itself (see above), when I console.log the output in my test I get for these Ref objects

{current: null}

My expected result is a correctly populated Ref object where current element points to the DOM element that was created by React when it rendered this component.

Transfiguration answered 11/12, 2019 at 20:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.