You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// test.jsimportReactfrom"react"window.doSomethingWithThisDiv=element=>{constnewEl=document.createElement("div")newEl.innerText="hello world"element.appendChild(newEl)}constcontext=React.createContext(null)exportconstProvider=({ children })=>{constmyRef=React.useRef(null)const[showDiv,setShowDiv]=React.useState(false)constcontextValue=React.useMemo(()=>{return{
showDiv,
setShowDiv
}},[showDiv,setShowDiv])React.useEffect(()=>{if(showDiv){window.doSomethingWithThisDiv(myRef.current)}},[showDiv])return(<context.Providervalue={contextValue}>{showDiv&&<divref={myRef}/>}{children}</context.Provider>)}exportconstuseTest=()=>{returnReact.useContext(context)}
// test.spec.jsimportReactfrom"react"importsinonfrom"sinon"import{renderHook}from"@testing-library/react-hooks"import{Provider,useTest}from"test"describe("testing context",()=>{it("works",()=>{constspy=sinon.spy(window,"doSomethingWithThisDiv")const{ result }=renderHook(useTest,{wrapper: ({ children })=><Provider>{children}</Provider>})result.current.setShowDiv(true)expect(spy.callCount).to.equal(1)})})
Error message due to the ref being null in the effect in test.js
warning Error: Uncaught [TypeError: Cannot read property 'appendChild' of null]
Reproduction:
See the code snippets above
Problem description:
Apologies for the super contrived example, but I was luckily able to reproduce the same issue I am seeing in my much more complicated application. Basically I am testing some features of a React context which exposes some state and an API to interact with that data. I am doing so by testing a custom hook which exposes the context to its users. In the Provider, in addition to the children it renders, there is some conditional UI which renders when some state is set to true, this particular div is assigned a ref so that it can be referenced later in an effect (in my real application I mount a sign in widget to this div from a third party identity provider). What is weird is that when I run this example live, I can see the ref is set just fine, but when running the unit tests the ref's value is always null even when the state is set to true.
The text was updated successfully, but these errors were encountered:
This had me stumped for a while as I it all looked right to me but it was very clearly never setting the ref when rendering. I managed to trace it to a relatively old (likely predating the current ref API) issue with react-test-renderer, where the takeaway is that because there is no DOM that the component gets rendered into, there is nothing for the ref to be set to. While this is annoying it does sort of make sense to me.
The issue goes on to mention a workaround that doesn't help you very much because you have no control over what we pass to react-test-renderer internally.
So where to from here? Well, you could not use this library for testing your hook and use @testing-library/react instead by creating a small test component and use it to render it instead. Given most of the login appears to be in the Provider, this might be the best approach anyway.
Alternatively, there is an in progress PR (which I admittedly haven't touched in a while), for adding the ability to use react-dom to render instead of react-test-renderer, so you might consider holding out for that. (The quickest way to get that moving is to jump into the PR and/or the issues it mentions and give me feedback and encouragement that it is actually useful to someone)
Finally, we could provide an option to allow setting the options when rendering to provide something to createNodeMock, but I'm not sure what that would look like right now and given the PR mentioned above, it's unlikely to be removed after that change goes in anyway.
@mpeyper thanks for the information. Seems like a lot going on. I agree with you that my best option is to probably not use this library to test my scenario for now. However, the ability to use react-dom as a render sounds like an interesting option to have. I may consider looking into that PR when I have some time to see if there is anything that I could do to help.
Feel free to close this or link it to that PR you have open now.
react-hooks-testing-library
version: 3.2.1react-test-renderer
version: 16.9.0react
version: 16.9.0node
version: 12.9.0npm
(oryarn
) version: yarn v1.21.1Relevant code or config:
What you did:
NODE_ENV=test mocha --opts path/to/opts test.spec.js
What happened:
Error message due to the ref being null in the effect in test.js
Reproduction:
See the code snippets above
Problem description:
Apologies for the super contrived example, but I was luckily able to reproduce the same issue I am seeing in my much more complicated application. Basically I am testing some features of a React context which exposes some state and an API to interact with that data. I am doing so by testing a custom hook which exposes the context to its users. In the Provider, in addition to the children it renders, there is some conditional UI which renders when some state is set to true, this particular div is assigned a ref so that it can be referenced later in an effect (in my real application I mount a sign in widget to this div from a third party identity provider). What is weird is that when I run this example live, I can see the ref is set just fine, but when running the unit tests the ref's value is always null even when the state is set to true.
The text was updated successfully, but these errors were encountered: