从单元测试中的导航模拟 addListener
Mock addListener from navigation in unit test
像这样从导航中使用 addListener,
useEffect(() => {
const navigationSubscription = props.navigation.addListener(
"willFocus",
() => setFocused(true)
);
return navigationSubscription.remove; //navigationSubscription is undefined here.
}, []);
这是测试文件中的代码片段,
const componentStub = (props) => {
return (
<Provider store={store}>
<TestComponent
navigation={{
navigate: jest.fn(),
addListener: jest.fn().mockImplementation((event, callback) => {
callback();
//remove: jest.fn();
}),
canGoBack: jest.fn(),
dispatch: jest.fn(),
getParent: jest.fn(),
getState: jest.fn(),
goBack: jest.fn(),
isFocused: jest.fn(),
pop: jest.fn(),
popToTop: jest.fn(),
push: jest.fn(),
removeListener: jest.fn(),
replace: jest.fn(),
reset: jest.fn(),
setOptions: jest.fn(),
setParams: jest.fn(),
// remove: jest.fn(),
}}
{...props}
/>
</Provider>
);
};
describe("TestComponent unit tests", () => {
it("Should render correctly", () => {
let componentUtils = render(componentStub());
const { toJSON } = componentUtils;
expect(toJSON().children.length).toBeGreaterThan(0);
});
});
我得到 TypeError: Cannot read properties of undefined (reading remove)
也许导航订阅尚未分配导致该错误,为了避免,我想在调用之前设置一个条件:
useEffect(() => {
const navigationSubscription = props.navigation.addListener(
"willFocus",
() => setFocused(true)
);
if(navigationSubscription){
return navigationSubscription.remove; //<=== here. To surely: return navigationSubscription?.remove
}
}, [props.navigation]); //<=== Then pass props.navigation to make component re-render when it change
mocked addListener
有一个小问题。当您调用 addListener
时,它期待返回值,但您没有从该模拟函数返回任何内容。
可能的解决方法是
const componentStub = (props) => {
return (
<Provider store={store}>
<TestComponent
navigation={{
navigate: jest.fn(),
addListener: jest.fn().mockImplementation((event, callback) => {
callback();
//returning value for `navigationSubscription`
return {
remove: jest.fn()
}
}),
canGoBack: jest.fn(),
dispatch: jest.fn(),
getParent: jest.fn(),
getState: jest.fn(),
goBack: jest.fn(),
isFocused: jest.fn(),
pop: jest.fn(),
popToTop: jest.fn(),
push: jest.fn(),
removeListener: jest.fn(),
replace: jest.fn(),
reset: jest.fn(),
setOptions: jest.fn(),
setParams: jest.fn(),
// remove: jest.fn(),
}}
{...props}
/>
</Provider>
);
};
describe("TestComponent unit tests", () => {
it("Should render correctly", () => {
let componentUtils = render(componentStub());
const { toJSON } = componentUtils;
expect(toJSON().children.length).toBeGreaterThan(0);
});
});
像这样从导航中使用 addListener,
useEffect(() => {
const navigationSubscription = props.navigation.addListener(
"willFocus",
() => setFocused(true)
);
return navigationSubscription.remove; //navigationSubscription is undefined here.
}, []);
这是测试文件中的代码片段,
const componentStub = (props) => {
return (
<Provider store={store}>
<TestComponent
navigation={{
navigate: jest.fn(),
addListener: jest.fn().mockImplementation((event, callback) => {
callback();
//remove: jest.fn();
}),
canGoBack: jest.fn(),
dispatch: jest.fn(),
getParent: jest.fn(),
getState: jest.fn(),
goBack: jest.fn(),
isFocused: jest.fn(),
pop: jest.fn(),
popToTop: jest.fn(),
push: jest.fn(),
removeListener: jest.fn(),
replace: jest.fn(),
reset: jest.fn(),
setOptions: jest.fn(),
setParams: jest.fn(),
// remove: jest.fn(),
}}
{...props}
/>
</Provider>
);
};
describe("TestComponent unit tests", () => {
it("Should render correctly", () => {
let componentUtils = render(componentStub());
const { toJSON } = componentUtils;
expect(toJSON().children.length).toBeGreaterThan(0);
});
});
我得到 TypeError: Cannot read properties of undefined (reading remove)
也许导航订阅尚未分配导致该错误,为了避免,我想在调用之前设置一个条件:
useEffect(() => {
const navigationSubscription = props.navigation.addListener(
"willFocus",
() => setFocused(true)
);
if(navigationSubscription){
return navigationSubscription.remove; //<=== here. To surely: return navigationSubscription?.remove
}
}, [props.navigation]); //<=== Then pass props.navigation to make component re-render when it change
mocked addListener
有一个小问题。当您调用 addListener
时,它期待返回值,但您没有从该模拟函数返回任何内容。
可能的解决方法是
const componentStub = (props) => {
return (
<Provider store={store}>
<TestComponent
navigation={{
navigate: jest.fn(),
addListener: jest.fn().mockImplementation((event, callback) => {
callback();
//returning value for `navigationSubscription`
return {
remove: jest.fn()
}
}),
canGoBack: jest.fn(),
dispatch: jest.fn(),
getParent: jest.fn(),
getState: jest.fn(),
goBack: jest.fn(),
isFocused: jest.fn(),
pop: jest.fn(),
popToTop: jest.fn(),
push: jest.fn(),
removeListener: jest.fn(),
replace: jest.fn(),
reset: jest.fn(),
setOptions: jest.fn(),
setParams: jest.fn(),
// remove: jest.fn(),
}}
{...props}
/>
</Provider>
);
};
describe("TestComponent unit tests", () => {
it("Should render correctly", () => {
let componentUtils = render(componentStub());
const { toJSON } = componentUtils;
expect(toJSON().children.length).toBeGreaterThan(0);
});
});