自从早上起,我非常恼火,因为如果没有这个无限循环,我将无法测试自定义钩子。
我的自定义钩子看起来像:
useGetObj1.tsx
export function useGetObj1(): [
{ obj1: IObj1 | null; obj2: IObj2 | null } | null,
Function
] {
const User = useSelector((state: IStoreState) => state.User);
const history: History = useHistory();
const resState = useState<{ obj1: IObj1 | null; obj2: IObj2 | null } | null>(null);
const setState = resState[1];
useEffect(() => {
async function setStateValue() {
let tmp = null;
const res = await ParseVerifObj1(User, history.location.pathname);
if (typeof res !== "number") {
res
? (tmp = {
obj1: res.obj1,
obj2: res.obj2,
})
: (tmp = { obj1: null, obj2: null });
setState(tmp);
} else if (res === -1) history.push("/HomePage");
}
setStateValue();
}, [history.location.pathname, User, setState]);
return resState;
}
我的测试如下:
useGetObj1.spec.js
jest.mock("axios");
jest.mock("react-router-dom", () => ({
useHistory: () => ({
push: jest.fn(),
location: {
pathname: "/path/web",
},
}),
}));
// make setup-jest file and put it later
import "axios";
import "babel-polyfill";
//
import React from "react";
import { mount } from "enzyme";
import { Provider } from "react-redux";
// import ParseVerifObj1 to mock it
import * as ParseVerifObj1 from "../path";
// custom hook tested here
import { useGetObj1 } from "../path";
import configureStore from "redux-mock-store";
// act to handle the Promise and the re-render of the renderHook
import { act } from "react-dom/test-utils";
// Utils Initial store
import { initialStore } from "../path";
import routeData from "react-router";
const mockStore = configureStore();
const mockLocation = {
pathname: "/",
hash: "",
search: "",
state: "",
};
jest.spyOn(routeData, "useLocation").mockReturnValue(mockLocation);
describe("useGetObj1.spec.js", () => {
let store;
beforeEach(() => {
store = mockStore(initialStore);
jest.clearAllMocks();
});
let results;
let wrapper;
const renderHook = (hook) => {
function HookWrapper() {
results = hook();
return null;
}
wrapper = mount(
<Provider store={store}>
<HookWrapper />
</Provider>
);
return results;
};
describe("Testing the custom hook : useGetObj1", () => {
it("useGetLesson is ran", async () => {
await act(async () => renderHook(useGetObj1));
expect(wrapper).toBeTruthy();
});
it("Testing the output adress values get from the ParseVerifObj1 function", async () => {
const spy = jest.spyOn(ParseVerifObj1, "ParseVerifObj1");
const lesson = Symbol("Obj1");
const session = Symbol("Obj2");
spy.mockReturnValue({
Obj1,
Obj2,
});
await act(async () => renderHook(useGetObj1));
expect(spy).toHaveBeenCalledWith(
initialStore.User,
"/path/web"
);
expect(spy).toHaveBeenCalled();
expect(results[0].Obj1).toBe(Obj1);
expect(results[0].Obj2).toBe(Obj2);
expect(results[1]).toBeInstanceOf(Function);
});
我知道将历史记录放入useEffect的依赖关系中不是一件好事,但是我得到了类似的警告
第39:6行:React Hook useEffect缺少依赖项:'history'。包括它或删除依赖项数组 我尝试了许多不同的实现,但是没有人解决问题并在没有警告的情况下进行编译
帮助:)
_ 解决方案 strong>
对我来说,解决方案是使用useRef避免这样的依赖要求:
const history: History = useRef(useHistory());
使用ref,您不再需要将其作为依赖项