jest-styled-components
jest-styled-components copied to clipboard
Property 'getChildContext' does not exist on type 'Component<{}, {}, any>' (TypeScript)
Using the functions from the theming section of the README in TypeScript, and getting the following error:
export const shallowWithTheme = (tree: React.ReactElement<{}>) => {
const context = shallow(<ThemeProvider theme={theme} />)
.instance()
.getChildContext();
^^^^^^^^^^^^^^^
return shallow(tree, { context });
};
error TS2339: Property 'getChildContext' does not exist on type 'Component<{}, {}, any>'.
This has something to do with enzyme’s instance()
returning a generic React component that doesn’t seem to have a getChildContext
method.
Has anyone else encountered this issue, and know of a workaround? Thanks!
If I understood right, getChildContext
does not exist anymore, as styled-components 4 is using the React 16 Context API. Even when "dumb casting" the returned component to any
and calling getChildContext
, you'll get a runtime error telling you that getChildContext
is not a function.
My workaround for now is:
import * as React from 'react';
import { mount, render, shallow } from 'enzyme';
import { ThemeProvider } from 'styled-components';
import * as theme from './theme';
export const mountWithTheme = (children: any) =>
mount(<ThemeProvider theme={theme}>{children}</ThemeProvider>);
export const renderWithTheme = (children: any) =>
render(<ThemeProvider theme={theme}>{children}</ThemeProvider>);
export const shallowWithTheme = (children: any) =>
shallow(<ThemeProvider theme={theme}>{children}</ThemeProvider>);
It’s pretty dumb, but works for the most part. Haven’t used it much yet to see if it’s missing out on anything by not passing context directly to enzyme.
Any other solution for this issue.
We have hundred of thousands components and now we got stuck to upgrade.
@dangodev mounting with the whole provider is not really helpful, as it spits out the whole theme object in my snapshots, and the styled parts still have a lambda function reference wherever I use the theme:
Theme provider with theme object in snapshot:
<ThemeProvider theme={
Object {
"colors": Object {
...
...
And styled components with theme-computed props:
border-radius: ",[Function],"px;
That's the reason why in the examples of jest-styled-components they want to setup the context and use that for the mount of your actual component.
That’s probably true @justusromijn because I don’t really use snapshots! 😅 They sound great in theory but in practice for us they turned out to be pure noise. In our tests we’ll specifically target the elements/styles/properties/text/etc. that should display in a scenario rather than play “spot the differences.” So I didn’t really notice that method not working for snaps.
Either way, it’s still an issue with the types for this library.
@dangodev I think when I switch to react hooks, I can get my snapshots to be better as well, since the React Tree becomes a lot more flat without all those wrapping HoC's or providers in a lot of cases.
Snapshot testing I only use more for regression, so I just add them in as an addition to specific functionalities that I test. Just a safety net :)
Maybe we could somehow swap the ThemeContext that is used by styled components, by defining our own ThemeContext that has a default value defined by us on test setup?
Then we wouldn't have to mount it with theme provider at all? (Am I right?)
Enzyme 3.10.0 adds a new API that makes it easy to wrap shallow() and mount() with context. It works perfectly with snapshots as far as I can tell.
Here's my Typescript code for a mount wrapper:
const mountWithTheme = (tree: ReactElement<any>, theme: DefaultTheme) => {
const WrappingThemeProvider: React.FC<{children: React.ReactChild}> =
(props) => (
<ThemeProvider theme={theme}>
{props.children}
</ThemeProvider>
);
return mount(
tree,
{wrappingComponent: WrappingThemeProvider} as MountRendererProps //Override typing because @types/enzyme doesn't have wrappingComponent yet https://github.com/DefinitelyTyped/DefinitelyTyped/pull/36667
);
};
I've opened a documentation fix request for jest-styled-components here: #256
Enzyme 3.10.0 adds a new API that makes it easy to wrap shallow() and mount() with context. It works perfectly with snapshots as far as I can tell.
Here's my Typescript code for a mount wrapper:
const mountWithTheme = (tree: ReactElement<any>, theme: DefaultTheme) => { const WrappingThemeProvider: React.FC<{children: React.ReactChild}> = (props) => ( <ThemeProvider theme={theme}> {props.children} </ThemeProvider> ); return mount( tree, {wrappingComponent: WrappingThemeProvider} as MountRendererProps //Override typing because @types/enzyme doesn't have wrappingComponent yet https://github.com/DefinitelyTyped/DefinitelyTyped/pull/36667 ); };
I've opened a documentation fix request for jest-styled-components here: #256
Works perfect for shallow rendering. However its doesn't work when I try the same solution for mounting. It seems like the theme prop is undefined. I have found many related open and closed issues, but none of these have a proper solution or workaround.
Can someone help me pls?
any updates or fixes? maybe it have sense to update README ?
ps: i'm using this workaround:
export const mountWithTheme = (children, theme = DefaultTheme) => {
ThemeConsumer._currentValue = theme
return mount(children)
}
I'm using this documentation and this is the reason why raise my hands and say: "I have the same problem."