Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Property 'getChildContext' does not exist on type 'Component<{}, {}, any>' (TypeScript) #217

Open
drwpow opened this issue Dec 6, 2018 · 11 comments

Comments

@drwpow
Copy link

drwpow commented Dec 6, 2018

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!

@niklaskorz
Copy link

niklaskorz commented Dec 9, 2018

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.

@drwpow
Copy link
Author

drwpow commented Dec 12, 2018

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.

@aminpaks
Copy link

aminpaks commented Jan 3, 2019

Any other solution for this issue.

We have hundred of thousands components and now we got stuck to upgrade.

@justusromijn
Copy link

@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.

@drwpow
Copy link
Author

drwpow commented Apr 9, 2019

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.

@justusromijn
Copy link

@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 :)

@jtomaszewski
Copy link

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?)

@JustinLex
Copy link

JustinLex commented Jul 8, 2019

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

@silltho
Copy link

silltho commented Aug 5, 2019

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?

@kerosan
Copy link

kerosan commented Jul 13, 2020

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)
}

@BirgitPohl
Copy link

I'm using this documentation and this is the reason why raise my hands and say: "I have the same problem."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants