Closed minznerjosh closed 5 years ago
I am experiencing an issue with this as well as it relates to snapshot testing with Redux connected children. The below mock works well
const mockContext = jest.fn(/* mock values returned here */);
jest.mock('some-module', () => ({
FooConsumer: ({ children }) => children(mockContext())
}));
and snapshots look great for general React components
shallow(<Test />).dive();
However when the child is a Redux connected component, I get this for a snapshot
<Connect(FooComponent)
/* props */
>
<FooConsumer>
<Component />
</FooConsumer>
</Connect(FooComponent)>
switching to using mount
in this case and creating a mock store causes jest or enzyme to hang indefinitely.
Just as an aside, react-redux has already made their change to the new context api as of v6.0.0 which released just last month so consider me as the first of a flood of people that will be running into this issue shortly. :)
Downgrading to react-redux v5.1.1 in the meantime.
Understood; there's already a bit of discussion on https://github.com/reduxjs/react-redux/issues/1161 about it.
It's perhaps worth noting that version 4 of styled-components
is notoriously difficult to test using Enzyme due to the Context API. See e.g.
https://github.com/styled-components/jest-styled-components/issues/191
Closed by #1960 and #1966.
Hi, I am not sure this related to this issue but when I tried to mount a styled component I get this weird DOM output from enzyme using debug()
function.
<StyledComponent type="search" onClick={[undefined]} roundCorner={true} forwardedComponent={{...}} forwardedRef={{...}}>
I would expect it to mount into actual DOM but this doesn't seems the case. As mentioned by @csvan , this has created issue when come to snapshot testing a styled component as it doesn't output the actual DOM here.
@vKongv definitely entirely unrelated to this issue; .debug never shows the mounted html, only the enzyme tree. Enzyme does not support or recommend snapshot testing.
Enzyme does not support or recommend snapshot testing. @ljharb can you cite this?
@ryanirilli please file another issue to discuss that; as for a citation, i just said it :-)
@heath-freenome eg https://airbnb.io/enzyme/docs/api/ShallowWrapper/getWrappingComponent.html?
It's been quite some time since the
createContext()
API shipped in react, and I'd love to help out in implementing "full support" for that API in enzyme ASAP. (Before the libraries many of us depend on [react-router, react-redux, etc] switch from using the deprecated, legacy context API to the new, fully-supported API.)However, based on my reading of many
createContext()
-related issues in this repo, I don't have a clear idea of what "full support" forcreateContext()
in enzyme looks like. So I've created this issue so we can hammer it out.Assumptions
I'm walking into this discussion with the following assumptions. Please challenge them if they don't make sense!
shallow()
andmount()
.createContext()
and the legacy context API simultaneously, just like react.Enzyme's Current (Legacy) Context APIs
I've seen some issues (#1913, #1840) that imply that
options.context
should somehow work with thecreateContext()
API in the future. However, as per my assumptions, I don't understand how this API could supportcreateContext()
. For example, how would this work?The only API I could imagine still making sense for
createContext()
iswrapper.context()
. But even then, it would only be for class components that are using thecontextType
feature added inreact@16.6
, as that's the only part of the API that setsthis.context
in a component.An Idea for Moving Forward
The current context APIs
I think we should move forward with the idea that the existing context APIs (
options.context
,.setContext()
, perhaps.context()
) are only for legacy context, and will never have anything to do with thecreateContext()
API. We should update the docs to reflect this immediately.The
createContext()
APII'm of the opinion that enzyme shouldn't actually add any new APIs for
createContext()
.createContext()
is all about just rendering components! It doesn't involve component methods likegetChildContext()
or static properties likecontextTypes
andchildContextTypes
. If enzyme can handle renderingcreateContext()
's<Consumer />
and<Provider />
, it doesn't need to do anything else!For clarification, here's how one would translate the use of the legacy context APIs using
createContext()
!options.context
shallow( , {
context: { foo: 'hello', bar: 'world' },
});
mount( , {
context: { foo: 'hello', bar: 'world' },
childContextTypes: { foo: PropTypes.string, bar: PropTypes.string },
});
setContext()
const sWrapper = shallow( , { context: { someContext: 'foo' } });
sWrapper.setContext({ someContext: 'bar' });
const mWrapper = mount( , { context: { someContext: 'foo' } });
mWrapper.setContext({ someContext: 'bar' });
The only problem I see with this approach is that, if you must wrap your component in
<Provider />
s to get your context, your component will never be the root, and it is therefore not possible to call.setProps()
on it. To address this, I'm working on #1960.Thanks for reading! Looking forward to discussing!