I have a component:
RandomGif.js
import React, { Component } from "react";
import Gif from "./Gif";
import Loader from "./library/Loader";
import { fetchRandom } from "../resources/api";
class RandomGif extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
state = {
loading: false,
gif: null
};
componentDidMount() {
this.handleClick();
}
async handleClick() {
let gifContent = null;
try {
this.setState({
loading: true
});
const result = await fetchRandom();
if (!!result && result.data) {
gifContent = {
id: result.data.id,
imageUrl: result.data.images.downsized_large.url,
staticImageUrl: result.data.images.downsized_still.url,
title: result.data.title
};
}
} catch (e) {
console.error(e);
} finally {
this.setState({
loading: false,
gif: gifContent
});
}
}
render() {
const { gif, loading } = this.state;
const showResults = gif && !loading;
return (
<div className="random">
{!showResults && <Loader />}
<button className="btn" onClick={this.handleClick}>
RANDOMISE
</button>
{showResults && <Gif data={gif} />}
</div>
);
}
}
export default RandomGif;
If I call methods directly from the instance of this component, I can successfully test that the state is being updated. However, If I simulate a button click, nothing gets updated and the test fails. I've tried setImmediate and setTimeout tricks but those are not working.
So far I've not able to write a test case for:
- Simulating button click.
- Simulating lifecycle method.
This is what I've come up with so far.
RandomGif.spec.js
import React from "react";
import { shallow, mount } from "enzyme";
import RandomGif from "./RandomGif";
describe("Generate Random Gif", () => {
it("should render correctly.", () => {
const wrapper = shallow(<RandomGif />);
expect(wrapper).toMatchSnapshot();
});
it("should load a random GIF on calling handleSearch fn.", async () => {
const wrapper = mount(<RandomGif />);
const instance = wrapper.instance();
expect(wrapper.state("gif")).toBe(null);
await instance.handleClick();
expect(wrapper.state("gif")).not.toBe(null);
});
it("THIS TEST FAILS!!!", () => {
const wrapper = mount(<RandomGif />);
expect(wrapper.state("gif")).toBe(null);
wrapper.find('button').simulate('click');
wrapper.update()
expect(wrapper.state("gif")).not.toBe(null);
});
});
api.py
export const fetchRandom = async () => {
const url = `some_url`;
try {
const response = await fetch(url);
return await response.json();
} catch (e) {
console.error(e);
}
return null;
};
Please help me figure out the missing pieces of a puzzle called 'frontend testing'.