-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
shallow().dive() does not work with react-redux Provider #2202
Comments
+1 here, doesn't seem to work for me either.
throws this
|
Same problem, are there any plans to fix this? Also, does anyone have a workaround that can be used until it is fixed? |
Big corporate app - same issue. If we want to move forward and start using Redux with Hooks we need this fixed. A work around would be great. Right now we only have one component that uses .dive() heavily and if someone figures out a workaround that would be great. |
Any update on how best to get around this? Or if this will be tackled? |
Same here 💃 |
Try with the |
Same here. seems like enzyme and redux hooks are not getting along. |
@idangozlan, shallow() doesn't work with React's useContext hook. If you're using a version of react-redux higher than 5.1.1, you're going to have a bad time dealing with contexts. See this comment for some workarounds. // Bare component.
const Component = () => {
return <div>Hello World</div>;
};
// Redux connected component.
const ConnectedComponent = connect()(Component);
it('inject store work', () => {
// Inject store directly into connected component.
const wrapper = shallow(
<ConnectedComponent store={mockStore()} />
);
expect(wrapper).toMatchSnapshot();
}); |
@KenLui it's still not helpful, as the component not getting rendered... it's rendering the snapshot as:
|
enzyme doesn't have snapshot support, nor recommend snapshot testing - the closest thing is |
right, but even when running |
@idangozlan with shallow, you need one |
@idangozlan that's why i suggested using the const wrapper = shallow(<ComponentThatNeedsContext>, {
wrappingComponent: ContextProvider
});
wrapper.debug() |
@ljharb Still happening ( The sample code is: Test.js:
The test:
|
Indeed, I tried it myself again and even without snapshots etc, the problem is that |
Yes, that's very true. React hooks don't provide any hooks for testing purposes, so there's nothing for enzyme to interact with. You'd have to use the non-hook version of react-redux to be able to test it properly. |
@ljharb do you expect any feature like that will be available in the future? |
@idangozlan i certainly hope so - but it would require react to expose API hooks into how hooks work, and/or to implement support for such things in the shallow renderer. |
Hi, @ljharb How to invoke the const wrapper = shallow(
<MockProvider>
<LottoPyoContainer {...props} />
</MockProvider>
);
console.log(
wrapper
.dive()
.find('Connect(EcommerceBarContainer)')
.shallow({ wrappingComponent: MockProvider }) // error on this line
.debug()
); What happens here is: The <Connect(EcommerceBarContainer) instructionText={{...}} totalCost={1}>
<EcommerceBarLottoContent lineCountLotto={[undefined]} />
</Connect(EcommerceBarContainer)> Now I want to render the But Could not find "store" in the context of "Connect(EcommerceBarContainer)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(EcommerceBarContainer) in connect options. So, my question is: how to invoke the chaining |
Any solution for this issue, out there? |
Same Problem. Found a temporary solution though
|
Bump on this issue - related to #2174 Currently looking like theres no way to shallow render when using the useContext hook with enzyme. Has there been any progress on this? |
Hey, |
@vojtatranta how do inject it when the connected component is actually a child? const wrapper = shallow(<MyComp />);
connst connected = wrapper.find('Connect(Something)');
connected.dive() // doesnt work
connected.dive({ context: { store } }) // doesnt work
connected.shallow() // doesnt work
connected.shallow({ context: { store } }) // doesnt work |
@chris-fran pass the store as prop to connect HOC. |
I was having issues with TypeScript and React-Redux Provider. I don't know if this helps anyone but I was able to get a DOM snapshot via the below code.
testUtils.ts export const storeFactory = (initialState: any) => {
return createStore(rootReducer, initialState);
}; test.tsx const connectedSetup = (initialState={}) => {
const store = storeFactory(initialState);
const wrapper = shallow(<ConnectedSplashScreen store={store}/>).dive().dive();
console.log(wrapper.debug({verbose:true}));
return wrapper;
}; Though I do receive a Type error on 'store' on this line
|
Same issue for me, such a shame as replacing connect with the hooks removes so much boilerplate |
For me using mount return undefined in snapshot too |
|
Separately, enzyme doesn't support or recommend using snapshot testing; the closest is |
I add
in second test
I get this
|
Using |
@renjithspace could you please explain that code snippet. What is ContextProvider in this case? |
@anosov-otg for example: An HOC of React redux provider import { Provider } from 'react-redux' |
Closing; if |
|
@anosov-otg the first and third are fine, I'd expect the second to work with |
const wrapper = shallow(<ComponentThatNeedsContext>, {
wrappingComponent: ContextProvider
}); what about provider with store..where do you put send in a store above? Unless I'm missing some context :) how is this allowing us to send in a store? If this is not what you were thinking please elaborate: import { Provider } from "react-redux";
const wrapper = shallow(<ComponentThatNeedsContext>, {
wrappingComponent: Provider
}); |
@dschinkel you'd use the |
tried it, I get import { Provider } from "react-redux";
const store = createStore(rootReducer, initialState, middleware); it('contains expected actions', () => {
const homePage = shallow(<HomePageContainer />, {
wrappingComponent: Provider,
wrappingComponentProps: store
});
expect(homePage.props().fetchFeaturedCompanies).to.exist;
expect(homePage.props().fetchCompanies).to.exist;
}); I won't derail this and can open another issue if need be. Is this something new? I wasn't one to use Provider a lot in the past because I sent in my store via props. |
|
referring to this for further discussion 2449 |
@dschinkel @anosov-otg We can tackle this in different ways. Solution 1:Create an HOC for your provider, here is an example with redux: // StoreProvider.js
import { Provider } from 'react-redux'
import store from 'path/to/store'
function StoreProvider() {
return (
<Provider store={store}>
{this.props.children}
</Provider>
)
} And use that in tests with // ComponentThatNeedsProvider.test.js
import { shallow } from 'enzyme'
import StoreProvider from 'path/to/StoreProvider'
import ComponentThatNeedsProvider from 'path/to/ComponentThatNeedsProvider'
const wrapper = shallow(<ComponentThatNeedsProvider>, {
wrappingComponent: StoreProvider
}); Solution 2:You can directly pass provider props with // ComponentThatNeedsProvider.test.js
import { shallow } from 'enzyme'
import { Provider } from 'react-redux'
import store from 'path/to/store'
import ComponentThatNeedsProvider from 'path/to/ComponentThatNeedsProvider'
const wrapper = shallow(<ComponentThatNeedsProvider>, {
wrappingComponent: Provider,
wrappingComponentProps: { store }
}); If you prefer DRY or if you have multiple providers with a bunch of props to pass, go with Solution 1 👍 |
@stella1013 https://medium.com/@DaveSchinkel/setting-up-mocha-js-to-run-typescript-42f3099450eb |
yea I have tried that but no luck with I ended up with this working for me (had to add a it('fetches featured companies', async () => {
const companies: Array<Company> = [companyStub]
mockGet('/api/v1/companies/featured', companies);
const homePage = shallow(<HomePageContainer store={store} />);
await homePage.childAt(0).props().fetchFeaturedCompanies();
const newState = store.getState();
expect(newState.companies.companies).to.not.exist;
expect(newState.companies.featuredCompanies).to.exist;
}); redux v7 re-introduced the ability to pass store as a prop directly onto React components (as I like it). |
The wrapping component only works for me when I use a full mount.
works but when using |
@ajGingrich i agree; the goal is that it works with |
I will leave my experience here it might help any folk with a similar project setup. In the project I work, we are using enzyme v
declare namespace JSX {
interface IntrinsicAttributes {
store?: unknown;
}
} With that now typescript is happy and we as well. And below a small example of how we do the shallow test for the connected components. import configureMockStore from 'redux-mock-store';
const mockStore = configureMockStore();
const storeFake = mockStore({ foo: 'bar' });
it('should render the wrapped component with the connected properties', () => {
const wrapper = shallow(<Component store={storeFake} />);
expect(toJson(wrapper)).toMatchInlineSnapshot(`
<ContextProvider
value={null}
>
<Component
dispatch={[Function]}
foo="bar"
store={
Object {
"clearActions": [Function],
"dispatch": [Function],
"getActions": [Function],
"getState": [Function],
"replaceReducer": [Function],
"subscribe": [Function],
}
}
/>
</ContextProvider>
`);
} Note: Not a native english speaker sorry for any typo or for a bad expressed idea. Please quote me if it is needed a bit of more explanation. Please check this post to have a more detailed explanaition on how to include the ts type extension in your project. |
I had the same problem using dive twice solved my issues.Thats interesting.
|
@coskunuyar one dive per HOC, yes. |
How come this issue has still no solution? React hooks has been introduced in 2019, and it is still not possible to access the redux store with react hooks during a shallow render.. |
@joan-saum and it will still have no solution in 2119, since it’s blocked on the react team providing hooks for testing/reaching into hooks. |
This is just a simple example - please assume that
Component
needs to have access to the react-redux context so I can useuseSelector()
in there, so something like.find(Component).dive()
won't workCurrent behavior
Expected behavior
API
Version
Adapter
The text was updated successfully, but these errors were encountered: