当我使用 fetch 从响应页面获取和发布数据时,我正在尝试使用 jest 编写测试。
当前的测试是这样的 - 我对如何确保正确的数据通过特定组件感到困惑。
测试本身目前看起来像这样,
import React from 'react';
import '@testing-library/jest-dom';
import { render } from '@testing-library/react';
import getSettings from 'components/onboarding/stages/useGetSettingsData.js'
import updateSettings from 'components/onboarding/stages/useUpdateSettings.js'
import Settings from 'components/onboarding/stages/useUpdateSettings.js'
describe('get settings', () => {
it('should load settings with no issues', () => {
getSettings().mockResolvedValueOnce({
power: 'magical',
potion: 'magilin',
potion_times: '[]',
potion_activity_times: '',
gender: 'Male',
age: '30',
});
const {getByText, getByLabelText,debug} = render( <Settings/> )
expect(heading).toBeInTheDocument();
expect(GetSettings)
});
});
测试这个获取用户数据的功能,
import { useEffect, useState } from 'react';
export default function getSettings(auth) {
const [settings, setSettings] = useState(false);
useEffect(() => {
try {
const idToken = auth.getIdToken();
const response = fetch('/api/dashboard/get-settings', {
method: 'GET',
headers: new Headers({
Authorization: `Bearer ${idToken}`,
'Content-Type': 'application/x-www-form-urlencoded',
}),
});
const jsonReponse = response.json();
if (!jsonReponse.error) {
setSettings(jsonReponse.settings);
} else {
setSettings({
power: 'magical',
potion: 'magilin',
potion_times: '[]',
potion_activity_times: '',
gender: 'Male',
age: '30',
});
}
} catch (error) {
console.log('Error happened in decrypting token', error);
}
}, [settings]);
return settings;
};
这是设置设置,
import { loadingReducer } from 'components/onboarding/stages/loadingReducer';
export default function updateSettings({ newSettings, auth, initialState }) {
const [state, dispatch] = loadingReducer(loadingReducer, initialState);
dispatch({ type: 'LOADING' });
try {
const idToken = auth.getIdToken();
const response = fetch('/api/dashboard/set-settings', {
method: 'POST',
headers: new Headers({
Authorization: `Bearer ${idToken}`,
'Content-Type': 'application/json',
}),
body: JSON.stringify(newSettings),
});
// const jsonReponse = response.json();
// TODO: Create Notification Toast
} catch (error) {
console.log('Error happened in decrypting token', error);
}
dispatch({ type: 'FINISHED' });
return { isLoading: state.isLoading };
}
变成这样的组件,
function SettingsDetails() {
const auth = useAuth();
const { register, handleSubmit, errors } = useForm();
const initialState = {
isLoading: false,
};
// const settings = false
const settings = getSettings(auth);
const onSubmit = (data) => {
console.log('Submitting..');
const isLoading =updateSettings(data,initialState);
return isLoading
};
return (
<div className="md:grid md:grid-cols-3 md:gap-6">
<div className="md:col-span-1">
<h3 className="text-lg font-medium leading-6 text-gray-900">
Preferences
</h3>
<p className="mt-1 text-sm leading-5 text-gray-500">
Set your Personal Preferences
</p>
</div>
<div className="mt-5 md:mt-0 md:col-span-2">
<form onSubmit={handleSubmit(onSubmit)}>
<Dropdown
data-testid = "power"
registerInput={register}
optionLabel="power"
selectedOption={settings.power}
optionName="power"
allOptions={['ice', 'fire', 'Both']}
/>
.....
<button
className="inline-flex items-center justify-center px-5 py-2 border border-transparent text-base leading-6 font-medium rounded-md text-indigo-700 bg-indigo-100 hover:text-indigo-600 hover:bg-indigo-50 focus:outline-none focus:shadow-outline focus:border-indigo-300 transition duration-150 ease-in-out"
// variant={props.buttonColor}
// size={props.inputSize}
type="submit"
disabled={initialState.isLoading}
>
{initialState.isLoading ? (
<>
<span>Saving</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
className="animate-spin h-4 w-4 ml-3 fill-current"
>
<path d="M0 11c.511-6.158 5.685-11 12-11s11.489 4.842 12 11h-2.009c-.506-5.046-4.793-9-9.991-9s-9.485 3.954-9.991 9h-2.009zm21.991 2c-.506 5.046-4.793 9-9.991 9s-9.485-3.954-9.991-9h-2.009c.511 6.158 5.685 11 12 11s11.489-4.842 12-11h-2.009z" />
</svg>
</>
) : (
<span>Save</span>
)}
</button>
我对尝试模拟此获取数据功能的最佳方法有点迷茫 - 有什么最佳实践吗?
我只想确保页面呈现,呈现来自 getdata 函数的数据,并在提交到表单时正确保存数据。真的很难在网上找到任何资源来通过这种方式。
目前我在运行测试时遇到此错误,
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
提前致谢,
用于更新设置的加载减速器是这个 btw,
export default function loadingReducer(state, action) {
switch (action.type) {
case 'LOADING':
return { isLoading: true };
case 'FINISHED':
return { isLoading: false };
default:
return state;
}
}
答案 0 :(得分:1)
我想尝试的是在我的测试中不导入 getSettings
,而是模拟整个文件和钩子。
所以代替
import getSettings from 'components/onboarding/stages/useGetSettingsData.js'
做类似的事情
jest.mock('components/onboarding/stages/useGetSettingsData.js', () => {
return {
getSettings: jest.fn(() => {
return {
power: 'magical',
potion: 'magilin',
potion_times: '[]',
potion_activity_times: '',
gender: 'Male',
age: '30',
};
});
};
});
}
通过这种方式,您只需模拟整个 useGetSettingsData.js
文件,就可以测试您的组件更改。我希望这对你有用。