-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Testing styled component with enzyme #624
Comments
created a workaround but it might not be the best solution. const CHANNEL = '__styled-components__';
const broadcast = createBroadcast(themes.dark);
const nodeWithThemeProp = node => {
return React.cloneElement(node, { [CHANNEL]: broadcast.subscribe });
};
export function mountWithTheme(node, { context, childContextTypes } = {}) {
return mount(
nodeWithThemeProp(node),
{
context: Object.assign({}, context, {[CHANNEL]: broadcast.subscribe}),
childContextTypes: Object.assign({}, {[CHANNEL]: createBroadcast(themes.dark).publish}, childContextTypes)
}
);
} now i can get the wrapper component's |
Why don't you just use an actual Theme provider? Surely the code will end up looking less hacky. |
@philpl in this case it would be imposible to use shallow render of enzyme, cause the only rendered element will be ThemeProvider. |
Can we reopen this, none of the current ways of testing react together with styled components are adequate, @chuanxie's hack works but it's still a hack. |
@philpl first of all I want to test my components in isolation, so shallow rendering is what I need. |
would this work?
documentation here https://github.com/airbnb/enzyme/blob/master/docs/api/ShallowWrapper/dive.md |
The same problem described in the topic exists regardless of whether you shallow mount or full mount... if you add the ThemeProvider as the "root component" you lose access to the root node specific functions provided by testing helper libraries like |
I'm looking for a way to shallow render test my styled components in Enzyme as well and struggling. My previous tests would follow a simple wrapper.render.find('.selector') or expect(wrapper.html()).toEqual('...')) but I now have no way of accurately referencing the hashes. I've used css modules in these tests in the past and found it easy to reference the json map provided for the generated hashes but as far as I know there is no equivalent here. Any suggestions for a workaround would be greatly appreciated! |
@matthewvincent the solution is further up the thread, see my previous comment. |
My workaround for glamorous, should work with styled-components too: const shallowWithTheme = (children, options) => {
const wrapper = shallow(<ThemeProvider theme={theme}>{children}</ThemeProvider>, options)
const instance = wrapper.root.instance()
return wrapper.shallow({ context: instance.getChildContext() })
}
shallowWithTheme(<components.Button>Hello</components.Button>) |
Anyone know how to solve this when using |
I agree that it's hard to test using themes powered by ThemeProvider. I think @neoziro 's solution is very smart, and maybe a note regarding this in the docs would be nice. Allow me to side-note that currently my thought is not using a provider and instead have the theme in a raw JS file and importing it directly is smarter. It avoids exactly this testing issue that I've seen many people run into multiple times. |
When I use styled-components to make "building block" components defined in the same file as the "assembled" component, I am having a really difficult time targeting them in my tests using enzyme's For example, with this styled-component:
If I use an imported styled-component like
But I haven't found an elegant way to find the "building block" components like |
as @nfcampos stated, the only way I have found is to use dive:
|
chuanxie has the best solution further up this thread, it covers shallow rendering and access to root-specific methods. |
@chuanxie Is this for testing styled-components outside of this repo? I don't follow how you're referencing the |
Ah he left that out: import createBroadcast from 'styled-components/lib/utils/create-broadcast'; |
His code can be simplified a little too, did it for a client I work for, unfortunately can't post it right now. |
I tried the direct import like that and ran into the "fun" problem of Jest transforming the import. Isn't jest supposed to ignore |
You talking about auto-mocking? |
I thought that the error I posted a snapshot of was Jest trying to trasnform an import improperly? automocking is defaulted to off. |
No idea, I'm also using it with jest at BulbEnergy and didn't have that problem. |
It looks like you are trying to import ES6 module syntax, which isn't supported by any existing version of node. Are you sure you used the right path for your broadcast import? |
Is there anything like |
@three60five you can do it now with |
Again you keep linking to that comment when the better solution is up the page. |
@ohjames why is this a better solution? |
It supports access to root node specific methods on non-shallow renders in addition to the shallow rendering case. Also faster. |
Wrapping with export const mountWithTheme = (children, options) => {
const wrapper = mount(<ThemeProvider theme={injectTheme}>{children}</ThemeProvider>, options);
const instance = wrapper.root.instance();
return wrapper.mount({ context: instance.getChildContext() });
}; const wrapper = mountWithTheme(<DataContainer
configuration={testConfig}
authClient={authClient}
/>);
expect(wrapper.state().dataSummaries).to.deep.equal([]); as you can have a try, the Any idea or walkaround? 😢 |
The workaround has already been pasted in this very thread. |
@ohjames @JimmyLv I've been following this for a while w/o actually pointing out the obvious solution. Sorry for that! When there's no ThemeProvider context present, the StyledComponent defaults to the actual @chuanxie's workaround works perfectly as well, but will probably need some modifications after #1048 is merged. Btw, it's undesirable to test the entire ThemeProvider flow instead of just passing the prop or doing other, similar things anyway, since it tests our code. You don't need to test for styled-components to work correctly, since that's our responsibility 😉 cc @MicheleBertoli
Edit: I've opened an issue on jest-styled-components to write a helper or some docs to solve this problem in a central place. styled-components/jest-styled-components#61 This issue has been really noisy and not helpful for people to spot a workaround. If you're landing here and are searching for a solution, either use the If you think this issue should continue, don't open a new one, but msg me on Twitter or Gitter, or post at the new jest-styled-components issue to work on a solution please |
The same hacks are needed for ApolloProvider and many others so it'd be good to provide a solution for it in enzyme I think. They should allow dive() even in non-shallow components. |
I got theme defined in the app and the child component contains style like
color: ${props => props.theme.options.color};
if i use Enzyme to
mount
the parent component, it causeTypeError: Cannot read property of undefined
Is there any solution for this issue, i try to
setContext(__styled-component__)
in the test but it doesn't work.The text was updated successfully, but these errors were encountered: