【发布时间】:2019-06-30 11:25:03
【问题描述】:
需要通过主题来正确测试我的一些组件,使用情感 ThemeProvider 或 withTheme API。
实际上,我发现'styled-components' 存在同样的问题,它描述了here。根据 VladimirPesterev 的评论,我得到了这个 API 包装器:
import * as React from 'react'
import { shallow, mount, render } from 'enzyme'
import { ThemeProvider } from 'emotion-theming'
import theme from '../themes/default';
function wrapWithTheme (fn: Function, children: React.ReactChild, options: any): React.ReactChild {
const wrapper = fn(
<ThemeProvider theme={theme}>
{ children }
</ThemeProvider>,
options
)
return wrapper[fn.name]({
context: wrapper.instance().getChildContext(),
})
}
export function shallowWithTheme (component: React.ReactChild, options?: any) {
return wrapWithTheme(shallow, component, options);
}
export function mountWithTheme (component: React.ReactChild, options?: any) {
return wrapWithTheme(mount, component, options);
}
export function renderWithTheme (component: React.ReactChild, options?: any) {
return wrapWithTheme(render, component, options);
}
当我在测试中使用这些助手时,我得到一个错误:
TypeError: wrapper.instance 不是函数
看起来它的 API 已经过时了。上面链接的主题中还有来自 arka-na 的另一种解决方案,但我不知道如何将其应用于情感:
import { ThemeConsumer } from 'styled-components'
import defaultTheme from '../somewhere/theme'
export const shallowWithTheme = (children, theme = defaultTheme) =>
{
ThemeConsumer._currentValue = theme
return shallow(children)
}
更新 根据Yichaoz 的回答,我最终得到了这个sn-p:
import * as React from 'react'
import { shallow, mount, render } from 'enzyme'
import { channel, createBroadcast } from 'emotion-theming'
import * as PropTypes from 'prop-types';
import defaultTheme from '../themes/default';
const broadcast = createBroadcast(defaultTheme);
const defaultOptions = {
theme: defaultTheme,
context: {
[channel]: broadcast
},
childContextTypes: {
[channel]: PropTypes.object
}
};
function wrapWithTheme (fn: Function, component: React.ReactChild, options: any): React.ReactChild {
const mergedOptions = Object.assign({}, defaultOptions, options);
return fn(component, mergedOptions);
}
export function shallowWithTheme (component: React.ReactChild, options?: any) {
return wrapWithTheme(shallow, component, options);
}
export function mountWithTheme (component: React.ReactChild, options?: any) {
return wrapWithTheme(mount, component, options);
}
export function renderWithTheme (component: React.ReactChild, options?: any) {
return wrapWithTheme(render, component, options);
}
【问题讨论】:
标签: reactjs unit-testing enzyme emotion