I know this might look like a duplicate but i've been searching and trying various answers for hours. I'm trying to test that opacity of an element changes from 1 to 0 once an image has loaded. My code works fine, it's just the test i'm struggling with as i'm fairly new to testing.
I have tried mocking Image to automatically resolve onload as per the answer here: How to test img.onload using Jest?
I have also tried the original and updated methods in the upvoted answer here: Testing with React's Jest and Enzyme when simulated clicks call a function that calls a promise
Here's the relevant code in my component:
const HeroImage = (props) => {
const {
imageTint,
src,
srcSm
} = props;
HeroImage.propTypes = {
imageTint: PropTypes.number,
src: PropTypes.string.isRequired,
srcSm: PropTypes.string
};
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
awaitImage();
}, []);
const loadImageWithPromise = () => {
return new Promise(resolve => {
const image = new Image();
image.onload = resolve;
image.src = src;
});
};
const awaitImage = async () => {
await loadImageWithPromise();
setIsLoaded(true);
};
const initImgOpacity = isLoaded ? 0 : 1;
return (
<>
<div
className={`
${styles.heroBg}
${styles.initImg}`
}
data-test="heroImage"
style={
{backgroundImage: `linear-gradient(
rgba(0, 0, 0, ${imageTint || 0.3}),
rgba(0, 0, 0, ${imageTint || 0.3})
), url(${srcSm})`,
opacity: `${initImgOpacity}`}
}
>
</div>
<div
className={`${styles.heroBg}`}
data-test="heroImage"
style={
{backgroundImage: `linear-gradient(
rgba(0, 0, 0, ${imageTint || 0.3}),
rgba(0, 0, 0, ${imageTint || 0.3})
), url(${src})`}
}
>
</div>
</>
);
};
Here is the relevant test:
describe("HeroImage tests", () => {
let component;
const testProps = {
imageTint: 0.5,
src,
srcSm
};
beforeEach(() => {
global.loadImageWithPromise = () => Promise.resolve();
component = shallow(
<HeroImage
imageTint={testProps.imageTint}
src={testProps.src}
srcSm={testProps.srcSm}
/>
);
});
it("should make the opacity of the small image 0 once the large image has loaded", async () => {
// global.Image = class {
// constructor() {
// setTimeout(() => {
// this.onload();
// }, 10);
// }
// };
await tick();
component.update();
component.setProps({});
console.error("opacity: ", findByTestAttr(
component, "heroImage")
.at(0)
.props()
.style
.opacity
);
// setImmediate(() => {
// expect(findByTestAttr(
// component, "heroImage")
// .at(0)
// .props()
// .style
// .opacity).toBe("0");
// done();
// });
});
});
I know I probably don't need the component.update and setProps there but i've tried everything i can find and think of. No matter what I try, the opacity is always 1. Can anyone see what is wrong with this?
Thanks
Aucun commentaire:
Enregistrer un commentaire