Component to test
class Carousel extends React.Component {
state = {
slides: null
}
componentDidMount = () => {
axios.get("https://s3.amazonaws.com/rainfo/slider/data.json").then(res => {
this.setState({ slides: res.data })
})
}
render() {
if (!slides) {
return null
}
return (
<div className="slick-carousel">
... markup trancated for bravity
</div>
)
}
}
export default Carousel
Test
import React from "react"
import renderer from "react-test-renderer"
import axios from "axios"
import Carousel from "./Carousel"
const slides = [
{
ID: "114",
REFERENCE_DATE: "2018-07-02",
...
},
{
ID: "112",
REFERENCE_DATE: "2018-07-06",
...
},
...
]
jest.mock("axios")
it("", () => {
axios.get.mockImplementationOnce(() => Promise.resolve({ data: slides }))
const tree = renderer.create(<Carousel />).toJSON()
expect(tree).toMatchSnapshot()
})
snapshot only records null
, since at the moment of execution I suppose state.slides = null
.
Can't put my finger on how to run expectations after axios done fetching the data.
Most of the samples online either use enzyme, or show tests with async functions that return promises. I couldn't find one that would show example only using jest and rendered component.
I tried making test function async
, also using done
callback, but no luck.
in short:
it("", async () => {
axios.get.mockImplementationOnce(() => Promise.resolve({ data: slides }))
const tree = renderer.create(<Carousel />);
await Promise.resolve();
expect(tree.toJSON()).toMatchSnapshot()
})
should do the job
in details: besides you have mocked call to API data is still coming in async way. So we need toMatchSnapshot
call goes to end of microtasks' queue. setTimeout(..., 0)
or setImmediate
will work too but I've found await Promise.resolve()
being better recognizable as "everything below is coming to end of queue"
[UPD] fixed snippet: .toJSON
must be after awaiting, object it returns will never be updated
The accepted answer started to fail the next day. After some tweaking, this seems to be working:
import React from "react"
import renderer from "react-test-renderer"
import axios from "axios"
import Carousel from "./Carousel"
jest.mock("axios")
const slides = sampleApiResponse()
const mockedAxiosGet = new Promise(() => ({ data: slides }))
axios.get.mockImplementation(() => mockedAxiosGet)
// eventhough axios.get was mocked, data still comes anychrnonously,
// so during first pass state.slides will remain null
it("returns null initally", () => {
const tree = renderer.create(<Carousel />).toJSON()
expect(tree).toMatchSnapshot()
})
it("uses fetched data to render carousel", () => {
const tree = renderer.create(<Carousel />)
mockedAxiosGet.then(() => {
expect(tree.toJSON()).toMatchSnapshot()
})
})
function sampleApiResponse() {
return [
{
ID: "114",
REFERENCE_DATE: "2018-07-02",
...
},
{
ID: "114",
REFERENCE_DATE: "2018-07-02",
...
},
]
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.