0

I would like to ask if I have the variable useState in the component which is used as a condition that determines the element inside it will appear or not. How to mock the variable? So that I can test the element inside the condition if the value is 'login'.

   const [dataHistory,seDataHistory] = useState("")
   const [data,setData] = useState("firstTimeLogin")
        
    const func2 = () => {
     getData({
      item1: "0",
     }).
     then((res) => {
       funct();
     })
   }

   const funct = () => 
     {setData("login")}
        
   return  
     {data === "firstTimeLogin" && (
        <div><button onClick="funct2()">next</button></div>
     )}

     {data === "login" && (
        <div>flow login</div>
      )}
Nick Vu
  • 14,512
  • 4
  • 21
  • 31
syareen
  • 328
  • 2
  • 4
  • 15
  • where is your trigger point for `funct` in your JSX? – Nick Vu May 11 '22 at 05:56
  • Im sory, i have update my question. It display the first element inside 'firstTimeLogin' then after click it will prompt element inside 'login'. I dont know how to change the value so that it will print element inside 'login' – syareen May 11 '22 at 06:29
  • your `getData` is an internal function in your component too? I'm trying to figure out all your implementation for a possible help :D – Nick Vu May 11 '22 at 06:42
  • ya thanks2.. function getdata() is a function from other file which is import in that component – syareen May 11 '22 at 07:20

2 Answers2

1

Firstly, you need to add data-testid for your button

{data === "firstTimeLogin" && (
   <div><button onClick="funct2" data-testid="next-button">next</button></div>
)}

You called onClick="funct2()" which is to trigger funct2 immediately after re-rendering, so I modified it to onClick="funct2".

Note that you also can use next content in the button for the event click but I'd prefer using data-testid is more fixed than next content.

In your test file, you should mock getData and call fireEvent.click to trigger funct2()

import { screen, fireEvent, render } from '@testing-library/react';

//'/getData' must be the actual path you're importing for `getData` usage
jest.mock('/getData', () => {
   return {
      getData: () => new Promise((resolve) => { resolve('') }) // it's mocked, so you can pass any data here
   }
})

it('should call funct', async () => {
   render(<YourComponent {...yourProps}/>)
   const nextButton = await screen.findByTestId("next-button"); //matched with `data-testid` we defined earlier
   fireEvent.click(nextButton); //trigger the event click on that button
   const flowLoginElements = await screen.findByText('flow login'); //after state changes, you should have `flow login` in your content
   expect(flowLoginElements).toBeTruthy();
})
Nick Vu
  • 14,512
  • 4
  • 21
  • 31
  • get error getData is not a function. why ya? – syareen May 12 '22 at 00:48
  • i do like this.. . . jest.mock('/getData', () => { return { getData: new Promise((resolve) => { resolve(mockData) }) } }) . . my function at other file look like this export function getData(): Promise{ return fetchGetData('GET', getServer().data,{}) } – syareen May 12 '22 at 01:06
  • Ah my badd! it should be `getData: () => new Promise((resolve) => { resolve('') })` @syareen – Nick Vu May 12 '22 at 02:27
  • ady solve the promise error... but the element inside the 'login' doesnt prompt.. – syareen May 12 '22 at 04:34
0

You can create a button and onClick of the button call funct()

anandsr-dev
  • 67
  • 2
  • 5
  • This doesn't answer the OP question about testing. When asked for more info about their jsx code in a comment on they question, they modified the question to show they're already doing what you suggest. – Dave Amphlett May 11 '22 at 12:33