-1

I have a React child component which has button

export function Banner({argumentSetter}){
function handleOnClick(){
  argumentSetter(argument.READ);
}
return(
<div>
  <Button onClick={handleOnClick}>
    <Icon name="delete" type="filled">
      Discard
    </Icon>
  </Button>
</div>
)
}

And I have my argumentSetter in my parent component defined as following,

const [argument,setArgument] = useState<Argument>(argument.EDIT);
argumentSetter = useCallBack((val)=>{
setArgument(val);
},[argument]);

return(
  <div>
    <Banner argumentSetter={argumentSetter}/>
  </div>
)

How to get 100% test coverage using jest.

chandana
  • 1
  • 3
  • Not sure if there's a lot of use of `useCallback` in the code above. Every time `argument` updates, `argumentSetter` will update too. It might just make sense to directly use `setArgument` as a prop to `argumentSetter` because it seems like over optimization might actually slow down performance. – Harkunwar Nov 22 '21 at 20:59
  • I am setting the value of argumentSetter in child component and sending it back to parent component, that is the reason I wrote it in that way, iam new to jest, not able to test it. Can you help me with testing?. I dont mind for performance right now because iam worried only about testing the child component. – chandana Nov 22 '21 at 21:08
  • What library are you using for UI testing in Jest? – Harkunwar Nov 22 '21 at 21:52
  • I am using Enzyme – chandana Nov 22 '21 at 21:56
  • Are you planning to test the parent component as well, or just the child component, which is `Banner`? – Harkunwar Nov 22 '21 at 22:04
  • I want to test only the child component for now – chandana Nov 22 '21 at 22:08
  • Does the answer work? – Harkunwar Nov 24 '21 at 18:12
  • Yep, Thank you so much, you saved lot of my work – chandana Nov 24 '21 at 18:29
  • Could you rate the answer and resolve the question! – Harkunwar Nov 26 '21 at 22:05

1 Answers1

0

To test the banner, your code should be like the following

import React from "react";
import { mount } from "enzyme";
import { Banner } from "./Banner.js";
import { argument } from "./arguments.js";

it("Button click leads to argument.READ", async () => {
  let promiseResolve = null;
  const argPromise = new Promise((resolve) => {
    promiseResolve = resolve;
  });
  const argumentSetter = (arg) => promiseResolve(arg);
  const banner = mount(<Banner argumentSetter={argumentSetter} />);
  banner.find("button").simulate("click");
  const newArg = await argPromise;
  expect(newArg).toEqual(argument.READ);
});

Explanation:

We create an externally fulfillable promise variable, called argPromise which will resolve when promiseResolve is called, which is called when the argumentSetter is called. Hence, when the button click is simulated, it will resolve the updated argument to newArg variable (which should be argument.READ), and hence you can test if it matches your expectation.

This should hence cover all lines of your Banner component during testing.

Harkunwar
  • 653
  • 5
  • 10