-
-
Notifications
You must be signed in to change notification settings - Fork 145
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
Add a helper to quickly provide a theme context w/o the ThemeProvider HOC #61
Comments
Hi @philpl , what do you mean add I tried to add # ListItem.js
export default withTheme(ListItem) # ListItem.test.js
import ListItem from './ListItem'
const wrapper = mount(
<ListItem
id={summary.number}
theme={injectTheme}
/>); |
@JimmyLv This approach indeed doesn't work for But this is a nice example of why a helper for adding the theme context would be nice and can't always be replaced by just passing the |
Thanks for opening the issue @philpl, I agree this repo is the right place to discuss testing and I'm more than happy to think about a solution. |
How do you pass the |
Hello @chhuang, const Button = styled.button`
color: ${props => props.theme.main};
`
const theme = {
main: 'mediumseagreen',
} If you pass a theme prop to it: test('theming', () => {
const tree = renderer.create(
<Button theme={theme} />
).toJSON()
expect(tree).toMatchSnapshot()
}) it works as expected. |
Thanks @MicheleBertoli! Is it possible to pass the theme to the nested components? e.g. the test will break if I have another component using theme inside |
In that case, you can use the For example, suppose you have a const Wrapper = ({ children }) => <div>{children}</div> The following test works as expected: test('theming', () => {
const tree = renderer.create(
<ThemeProvider theme={theme}>
<Wrapper>
<Wrapper>
<Wrapper>
<Button />
</Wrapper>
</Wrapper>
</Wrapper>
</ThemeProvider>
).toJSON()
expect(tree).toMatchSnapshot()
}) I hope this helps, @chhuang. |
@MicheleBertoli one problem with passing the theme as a prop + taking a snapshot is that the whole theme gets caught in the snapshot. If the theme changes (a new color is added) the test will fail, which makes the test very fragile. |
@carlkenne that's true only if you are rendering the tree using Enzyme, but it doesn't apply to the |
@carlkenne if you are using Enzyme, you can try enzyme-to-json. |
@philpl new to open source, so forgive me for butting in, but is it unreasonable or undesirable to use the same workaround described in the previous thread as a 'blessed' method as part of this project? I've used that same workaround for testing some of my work with success, but it is fragile to upstream changes, as noted here. Sorry again for butting in! |
Thank you very much @dangoslen. |
Is there a way to test the text content of a styled component using enzymes
|
Hello @joetidee, your test would fail even without the To access the text of a styled component rendered with Enzyme's const text = wrapper.dive().find(StyledComponent_B).children().text(); I hope this helps. |
Thanks a lot, I've been tearing my hair out trying to find out why |
Unfortunately, I don't think this specific behaviour is documented somewhere @kjarnet. |
It's sometimes very inconvenient to have I came up with a solution (inspired by @chuanxie's workaround) that works on the current version of styled-components, but it doesn't work with styled-components 4. I'm still looking for a solution for that, which might be trickier since styled-components 4 uses the new React context API. Anyway, in case it's helpful for others, here's the solution that works with styled-components 3.3.3: import React from 'react'
import enzyme from 'enzyme'
import { ThemeProvider } from 'styled-components'
import * as theme from './theme'
/**
* Wrapper for enzyme's mount() that includes the theme for styled-components
*/
export function mountWithTheme(children, options = {}) {
return enzyme.mount(children, buildRenderOptions(options))
}
/**
* Wrapper for enzyme's shallow() that includes the theme for styled-components
*/
export function shallowWithTheme(children, options = {}) {
return enzyme.shallow(children, buildRenderOptions(options))
}
/**
* Wrapper for enzyme's render() that includes the theme for styled-components
*/
export function renderWithTheme(children, options = {}) {
return enzyme.render(children, buildRenderOptions(options))
}
let themeProvider
function buildRenderOptions(options = {}) {
const { context, childContextTypes } = options
if (!themeProvider) {
themeProvider = enzyme.mount(<ThemeProvider theme={theme} />, options)
.instance()
}
return {
...options,
context: {
...context,
...themeProvider.getChildContext(),
},
childContextTypes: {
...childContextTypes,
...themeProvider.constructor.childContextTypes,
},
}
} |
@mbrowne any thoughts? I just upgraded to styled components version 4 and from your comments it appears this isn't a feasible solution and I'm doing some progressive research now to see if there's another way around this. Just poking around the fire and researching a bunch of different articles online to try to fully understand what we are up against. |
@mbrowne ok so ultimately what I was trying to do was mount a component and test a click simulation and every attempt made would result in a prop from the theme being undefined. I reorganized some things around and it just worked. I ended up getting around the theme provider with a simple mount then find on the first nested element (Accordion). Here is the test:
Here is the Accordion component:
Prior to writing this post my onClick was bound to the div within the Accordion component and I moved it to the AccordionContainer. That actually made a pretty big difference and the theme is getting pulled through (at least I think it is I'll develop a mock test to verify that soon): By the way here is the full Accordion.spec.js (hopefully this helps someone else):
|
There have been a lot of workaround and a lot of confused users around how to test theming.
styled-components/styled-components#624
The general problem is that wrapping a StyledComponent element in the ThemeProvider is not acceptable as it won't allow access to all enzyme methods for example.
Thus it's desirable to write a quick helper that creates a theme context or sth similar. Maybe it should also just be solved using some documentation.
For better or for worse, I'm going to lock the issue on the SC repo and continue a discussion for a solution here, since this can be solved using a simple helper and some text, instead of a huge, elongated issue on the styled-components repo, where people don't immediately spot the right workaround.
cc @MicheleBertoli (sorry 😆 let's see if this goes well)
The text was updated successfully, but these errors were encountered: