我正在尝试测试一个既包含React Context的提供者又包含使用者的组件。请参阅下面的App.tsx。 该提供程序位于还处理状态的包装器类中。
如何模拟ConfigurationContextProvider包装器类,以便它可以正确地向消费者提供loadedStatus
值以测试App.tsx的各种呈现方式?
App.tsx:
public render(): React.ReactNode {
return (
<ConfigurationContextProvider>
<ConfigurationContext.Consumer>
{ ({
loadedStatus,
}): ReactElement => {
switch( loadedStatus ){
case ConfigStatus.GoodConfiguration:
return ( this.renderApp());
case ConfigStatus.NotLoaded:
return ( this.renderUnloadedApp() );
case ConfigStatus.BadConfiguration:
return ( this.renderBadConfiguration() );
}
}}
</ConfigurationContext.Consumer>
</ConfigurationContextProvider>
)}
ContextProvider.tsx:
export const ConfigurationContext = React.createContext<ConfigurationState | undefined>(undefined);
export enum ConfigStatus {
NotLoaded,
BadConfiguration,
GoodConfiguration
}
export interface ConfigurationState{
loadedStatus: ConfigStatus;
baseUrl: URL;
}
export class ConfigurationContextProvider extends Component< {}, ConfigurationState> {
constructor( props: {} ){
super(props);
this.state = {
loadedStatus: ConfigStatus.NotLoaded,
baseUrl: null
}
}
async componentDidMount(): Promise<void> {
await this.loadConfiguration();
}
setConfiguration(configuration: Response): void {
const URL_KEY = 'BASE_URL';
const URL_VALUE = configuration[URL_KEY];
if (!Object.prototype.hasOwnProperty.call(configuration, URL_KEY))
{
this.setState({ loadedStatus: ConfigStatus.BadConfiguration });
console.error(`Missing field in configs: ${ URL_KEY }`);
}
else {
try{
this.setState({
loadedStatus: ConfigStatus.GoodConfiguration,
baseUrl: new URL(URL_VALUE),
});
}
catch {
this.setState({ loadedStatus: ConfigStatus.BadConfiguration });
console.error(`Bad URL in environment configs - ${ URL_KEY } : ${ URL_VALUE }`);
}
}
}
loadConfiguration(): Promise<void> {
const configPromise: Promise<Response> = fetch('./env.json');
return configPromise.then( (response) => response.json())
.then( (config: Response) => this.setConfiguration(config));
}
render(): React.ReactNode {
return (
<ConfigurationContext.Provider value = { {
...this.state,
} }>
{this.props.children}
</ConfigurationContext.Provider>
)
}
}
答案 0 :(得分:0)
找到的最简单的方法是对ConfigurationContextProvider的spyOn loadConfig函数进行设置,并根据需要将响应设置为setConfig。这种方法可以测试各种结果,并根据需要进行全面的上下文/状态更新。
jest.spyOn(
ConfigurationContextProvider.prototype, 'loadConfiguration').mockImplementation(
function(this: ConfigurationContextProvider) {
this.setConfiguration( { BASE_URL: 'http://localhost:8080' });
return Promise.resolve();
}
);