我正在尝试对功能组件进行一些测试。我使用了一个setInterval来每隔几秒钟更改一条消息。对于我的测试,我似乎没有测试任何正在使用的东西。我试过jest.useFakeTimers();
此外,我正在设置useState。
组件:
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import styled from "styled-components";
// Array of strings
import { messages } from "./messages";
export const Wrapper = styled.div`
font-family: 'Lato', sans-serif !important;
box-sizing: border-box;
width: 100%;
display: block;
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
height: 100vh;
h1 {
font-size: 2rem;
color: rgb(100, 100, 100);
}
};
`;
const loadMessage = () => {
// this is the line that is not being tested.
return messages[Math.floor(Math.random() * messages.length)];
};
export const Loader = () => {
const [message, setMessage] = useState("Loading...");
useEffect(() => {
const id = setInterval(() => {
// this is the line that is not being tested.
setMessage(loadMessage());
}, 3000);
return () => clearInterval(id);
}, [message]);
return (
<Wrapper id="login-content">
<Row className="align-items-center h-100">
<Col className="col-md-12 mx-auto">
<div className="container text-center">
<h1 className="loader" data-testid="loader" aria-live="polite">
{message}
</h1>
</div>
</Col>
</Row>
</Wrapper>
);
};
测试:
import React from "react";
import { shallow } from "enzyme";
import { Loader } from "./Loader";
const doAsync = c => {
setTimeout(() => {
c(true);
}, 3000);
};
jest.useFakeTimers();
describe("Loader component", () => {
it("tests state", () => {
const wrapper = shallow(<Loader />);
const message = wrapper.find(".loader").text();
jest.advanceTimersByTime(3000);
const callback1 = () => {
expect(wrapper.find(".loader").text()).not.toMatch(message);
};
doAsync(callback1);
jest.useRealTimers();
});
});
我在酶的问题上遇到了困难:https://github.com/airbnb/enzyme/issues/2086
useEffect函数似乎不会在组件用浅渲染。
考虑到这一点,我必须做的是模拟UseEffect。
const doAsync = c => {
setTimeout(() => {
c(true);
}, 3000);
};
jest.useFakeTimers();
describe("Loader component", () => {
beforeEach(() => {
const useEffect = jest
.spyOn(React, "useEffect")
.mockImplementation(f => f());
});
it("tests state", done => {
const wrapper = shallow(<Loader />);
const message = wrapper.find(".loader").text();
jest.advanceTimersByTime(3000);
const callback1 = () => {
expect(wrapper.find(".loader").text()).not.toMatch(message);
};
doAsync(callback1);
jest.useRealTimers();
done();
});
});
这使我的测试通过,我得到了100%的覆盖率。