使用带有 AuthContext 的 React 测试库测试组件
Testing components using react testing library with AuthContext
我有一个跟进问题:
最上面的答案说,不要创建新的上下文,而是使用 context/AuthContext 中的 AuthContext for ,因为这是挂钩使用的上下文。
我对这到底意味着什么感到困惑(本来可以发表评论,但还没有足够的代表发表评论)--有人可以通过代码沙箱向我展示吗?
谢谢!
这只是说要使用自定义 hook/component 正在使用的相同 React 上下文,而不是其他一些“随机”身份验证提供程序。
示例身份验证上下文:
export const useAuth = () => useContext(AuthContext);
export const AuthProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
const signup = (email, password) => {
return auth.createUserWithEmailAndPassword(email, password);
}
const login = (email, password) => {
return auth.signInWithEmailAndPassword(email, password);
}
const logout = () => auth.signOut();
...
const value = {
currentUser,
signup,
login,
logout,
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
消费组件示例:
import { useAuth } from "../context/AuthContext"; // <-- specific context
export default function Dashboard() {
const { currentUser, logout } = useAuth(); // <-- specific context
...
return (
<div>
...
</div>
);
}
特定的 AuthProvider
组件需要出现在 React 树中的组件上方,以提供上下文和状态。
例如,如果您像单元测试一样创建另一个 React 上下文提供程序:
const AuthContext2 = createContext(); // AuthContext2 to disambiguate it here
并将组件包装在 AuthContext2.Provider
中,然后组件仍在导入和使用从上面的代码导出的 AuthProvider
。
答案是还要导入 AuthProvider
并为单元测试包装它,而不是创建一个全新的上下文。
import { AuthProvider } from "../context/AuthContext";
const AllTheProviders = ({ children }) => {
return (
<Router>
<AuthProvider>
{children}
</AuthProvider>
</Router>
);
};
const customRender = (ui, options) => {
render(ui, { wrapper: AllTheProviders, ...options });
};
更新
where would I feed in mock values?
重构上下文提供者,您必须使用一个“初始状态”道具,该道具用于设置上下文使用的初始状态。重构自定义测试渲染器以获取额外的参数并将它们传递给包装器。
@musicformellons
could you maybe make that refactor part of the answer...?!
当然,应该包括在内。
export const AuthProvider = ({ children, initialState }) => {
const [currentUser, setCurrentUser] = useState(initialState.currentUser);
...
const value = {
currentUser,
signup,
login,
logout,
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
测试
import { AuthProvider } from "../context/AuthContext";
const AllTheProviders = ({ children }) => {
return (
<Router>
<AuthProvider initialState={authState}>
{children}
</AuthProvider>
</Router>
);
};
const customRender = (ui, options, initialState) => {
render(
ui,
{
wrapper: props => (
<AllTheProviders {...props} initialState={initialState} />
),
...options,
},
);
};
我有一个跟进问题:
最上面的答案说,不要创建新的上下文,而是使用 context/AuthContext 中的 AuthContext for
我对这到底意味着什么感到困惑(本来可以发表评论,但还没有足够的代表发表评论)--有人可以通过代码沙箱向我展示吗?
谢谢!
这只是说要使用自定义 hook/component 正在使用的相同 React 上下文,而不是其他一些“随机”身份验证提供程序。
示例身份验证上下文:
export const useAuth = () => useContext(AuthContext);
export const AuthProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
const signup = (email, password) => {
return auth.createUserWithEmailAndPassword(email, password);
}
const login = (email, password) => {
return auth.signInWithEmailAndPassword(email, password);
}
const logout = () => auth.signOut();
...
const value = {
currentUser,
signup,
login,
logout,
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
消费组件示例:
import { useAuth } from "../context/AuthContext"; // <-- specific context
export default function Dashboard() {
const { currentUser, logout } = useAuth(); // <-- specific context
...
return (
<div>
...
</div>
);
}
特定的 AuthProvider
组件需要出现在 React 树中的组件上方,以提供上下文和状态。
例如,如果您像单元测试一样创建另一个 React 上下文提供程序:
const AuthContext2 = createContext(); // AuthContext2 to disambiguate it here
并将组件包装在 AuthContext2.Provider
中,然后组件仍在导入和使用从上面的代码导出的 AuthProvider
。
答案是还要导入 AuthProvider
并为单元测试包装它,而不是创建一个全新的上下文。
import { AuthProvider } from "../context/AuthContext";
const AllTheProviders = ({ children }) => {
return (
<Router>
<AuthProvider>
{children}
</AuthProvider>
</Router>
);
};
const customRender = (ui, options) => {
render(ui, { wrapper: AllTheProviders, ...options });
};
更新
where would I feed in mock values?
重构上下文提供者,您必须使用一个“初始状态”道具,该道具用于设置上下文使用的初始状态。重构自定义测试渲染器以获取额外的参数并将它们传递给包装器。
@musicformellons
could you maybe make that refactor part of the answer...?!
当然,应该包括在内。
export const AuthProvider = ({ children, initialState }) => {
const [currentUser, setCurrentUser] = useState(initialState.currentUser);
...
const value = {
currentUser,
signup,
login,
logout,
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
测试
import { AuthProvider } from "../context/AuthContext";
const AllTheProviders = ({ children }) => {
return (
<Router>
<AuthProvider initialState={authState}>
{children}
</AuthProvider>
</Router>
);
};
const customRender = (ui, options, initialState) => {
render(
ui,
{
wrapper: props => (
<AllTheProviders {...props} initialState={initialState} />
),
...options,
},
);
};