-
-
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
Not able to get to actions via props() via shallow #2449
Comments
TS isn't JS, and enzyme ships no types, so any type system errors are wildly out of scope of this project. |
So just wait..I had several questions in here...one of which was should we still be able to access props like this through enzyme shallow after redux 7. that's a big question here as well as the passing of store as props period via shallow without provider via Redux 7, and trying provider did not work so far. So there's a lot more than just "TS" going on here. |
You want: const homePage = shallow(<HomePageContainer />, {
wrappingComponent: Provider,
wrappingComponentProps: { store },
}); |
tried that and got Error: store.tsx const middleware = applyMiddleware(thunk);
const initialState = {};
const store = createStore(rootReducer, initialState, middleware);
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, RootState, unknown, Action<string>>;
export default store; it('contains expected actions', () => {
const homePage = shallow(<HomePageContainer />, {
wrappingComponent: Provider,
wrappingComponentProps: { store }
});
expect(homePage.props().fetchFeaturedCompanies).to.exist;
expect(homePage.props().fetchCompanies).to.exist;
}); Second try: const dummyStore = (state = {}) => ({
default: () => {},
subscribe: () => {},
dispatch: () => {},
getState: () => ({ ...state }),
});
it('contains expected actions', () => {
const homePage = shallow(<HomePageContainer />, {
wrappingComponent: Provider,
wrappingComponentProps: { dummyStore }
});
expect(homePage.props().fetchFeaturedCompanies).to.exist;
expect(homePage.props().fetchCompanies).to.exist;
}); Error: HomePageContainer.tsx class HomePageContainer extends Component<PropsFromRedux> {
async componentDidMount() {
const { fetchFeaturedCompanies, fetchCompanies, fetchCountries } = this.props;
await fetchFeaturedCompanies();
await fetchCompanies();
await fetchCountries();
}
render() {
const { companies, countries, featuredCompanies } = this.props;
return (
<HomePage
className="ft-homepage"
companies={companies}
countries={countries}
featuredCompanies={featuredCompanies} />
);
}
}
const mapState = (state: RootState) => ({
countries: state.country.countries,
companies: state.companies.companies,
featuredCompanies: state.companies.featuredCompanies
});
const mapDispatch = {
fetchCountries,
fetchCompanies,
fetchFeaturedCompanies
};
const connector = connect(
mapState,
mapDispatch
);
type PropsFromRedux = ConnectedProps<typeof connector>
export default connect(mapState, mapDispatch)(HomePageContainer); |
In this case tho, you're using |
with
You do have to pass a store with a connect container or it'll complain that it can't find one from context or props. I was passing store via props for the past 5 years, when this stuff was all happy and working prior to Redux 7 I really truly do hate TS 👿 it('contains expected actions', () => {
const homePage = shallow(<HomePageContainer />).dive();
expect(homePage.props().fetchFeaturedCompanies).to.exist;
expect(homePage.props().fetchCompanies).to.exist;
});
good luck making that "happy" because my component is using type PropsFromRedux = ConnectedProps<typeof connector> sigh, just forget it...this is becoming one pile of smelly poop. |
closing it, thanks for your efforts @ljharb I'm spent...giving up on this for now. |
TS has nothing to do with it. Figure out what makes your tests pass, and then use ts-ignore as needed until the real code passes the typecheck. |
Like I said this code when it was using store as props (without provider) was working just fine for years. The real questions had to do with Enzyme + React-Redux 7 combo and where enzyme lies with all that. TS is an overall major pain in the ass lets be honest. One more variation I tried just for the records, and again connect does need a store or it'll complain: Part of the error I had missed for
so changed it since dummyStore is returning an object literal: it('contains expected actions', () => {
const homePage = shallow(<HomePageContainer />, {
wrappingComponent: Provider,
wrappingComponentProps: { store: dummyStore() }
});
expect(homePage.props().fetchFeaturedCompanies).to.exist;
expect(homePage.props().fetchCompanies).to.exist;
}); Error: stack trace
now we're back to the same old issue. Sounds like it might be treating context as looking for a react hook context. I'm not using hooks. But it looks like the store we're passing to Provider seems to be getting to provider, just that connect isn't finding it in context still so it makes me think there's some issue with context with enzyme/connect/redux going on here. |
went back to ignoring TS and trying store as prop again: it('contains expected actions', () => {
// @ts-ignore
const homePage = shallow(<HomePageContainer store={fakeStore(
{
country: {
countriesReceived: true,
countries: [countryStub]
},
companies: {
companiesReceived: true,
companies: [companyStub],
}
}
)}/>);
expect(homePage.props().fetchFeaturedCompanies).to.exist;
expect(homePage.props().fetchCompanies).to.exist;
}); AssertionError: So for some reason |
I also just verified with the Redux team that store as a prop on the component under test (no need for Provider) was re-introduced in React-Redux v7. So that leaves us with a possible enzyme issue here when it can't find that prop anymore on the surface area of the shallowed component? Why would these tests that were passing fine with enzyme shallow before v7 of Redux no longer work? You say it has nothing to do with TS but I added |
the fix: |
enzyme - like all runtime javascript code - doesn't know about, see, or care about type notations. Adding anything in type-space should have no impact on value-space. Glad you found a fix. |
so the real problem was how you have to access things through Redux now via v6 or 7. I had to add One person thinks it's because: this person was talking about Redux and Connect. So the recent React-Redux/Connect upgrade did effect my tests here and enzyme no longer worked the way I had it because the SUT in this case connect which is part of it, changed. This is pretty fragile anyway but...just thought I'd put that in here. Testing through connect is always going to be like this when you test through third party HOCs like this, which is why it's important to just push your logic out of your Views and decouple or just not use stuff like Connect in the first place. Also to get rid of the issue of TS complaining about store is not a recognized prop from tests, I added a test.d.ts file to my test folder with: declare namespace JSX {
interface IntrinsicAttributes {
store: any;
}
} in package.json, then reference it: |
When I do this
It generates error
Any fix for this
|
The same issue found. Not able to pass the store props in redux Provider. Did anyone get any solution? Versions: |
prior to redux 7:
after Redux 7 I don't think you can just pass in store as a prop anymore. I thought that they added back that ability? I don't remember where they landed with that.
So since I was getting an error that store is not a property, I had to wrap this in a garbage provider to even get this to compile again after upgrading Redux:
But after doing so, TS complains that store is not a prop:
expected undefined to exist
Here's yet another old test that tries to get to an action via props
so it no longer is able to get at props this way or something after Redux 7?
Sigh it's been a while, totally forgot this thread reduxjs/react-redux#1161
can anyone fill me in on the above, if this is even possible in Redux 7 both sending in a store as a prop and also being able to access actions like this as my existing tests were doing with props()?
My preference is:
I like testing the surface area via props.
The text was updated successfully, but these errors were encountered: