Enzyme: Shallow with Redux: Could not find "store" in the context

Created on 19 Sep 2020  路  12Comments  路  Source: enzymejs/enzyme

Does anyone know how I can get TS happy here with my typed Container? I also recently converted some older Redux connected components to use TS and also Redux v7

I just added TS to some existing tests and want to keep store passed as a prop somehow.

Notice I also had to change my container after converting to TS.. so I had to add RootState to it. I'm using enzyme shallow but there must be some way with a container to send store through still I assume with TS...

I am using store as a dummy basically. I just don't know how to tell the container with TS to let store still be an incoming prop here.

my test has:

beforeEach(() => {
  store = store();
  homePage = shallow(<HomePageContainer store={store} />).dive().find('.ft-homepage');
});

Error: Could not find "store" in the context of "Connect(HomePageContainer)"

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);
shallow question

All 12 comments

forgot you could wrap with provider around shallow. I've just done it with the store prop so long and preferred it (it's just a lot less verbose and simple), that I totally forgot I could do the "_gross_" way since I think Redux and/or React (one of the two) doesn't let you pass store as a prop anymore 馃槴

const homePage = shallow(<Provider store={store}><HomePageContainer /></Provider>).dive().find('.ft-homepage');

@dschinkel use the wrappingComponent and wrappingComponentProps options instead of needing dive.

Yup and I tired that already.

const interviewContainer = shallow(<Router>
  <InterviewContainer
    match={{
      params: { companyId: 1 },
      isExact: false,
      path: "/interviews/companies/:companyId",
      url: `/api/v1/companies/${company.id}`
    }}
    store={store}
  />
</Router>);

const interview = interviewContainer.dive().dive().find(".ft-interview");

OR
const interview = interviewContainer.dive().dive().dive().find(".ft-interview");

Error: ShallowWrapper::dive() can only be called on components

And:

const interviewContainer = shallow(<InterviewContainer
  match={{
    params: { companyId: 1 }, 
    isExact: false, 
    path: "/interviews/companies/:companyId", 
     url: '/api/v1/companies/${company.id}'
  }}
 />,
  {
    wrappingComponent: Router,
    wrappingComponentProps: { store: store }
  }
);

const interview = interviewContainer.dive().find(".ft-interview");

TypeError: Cannot read property 'prototype' of undefined
_It does not matter if I dive more for this second example_, the Router wrappingComponent fails here..it outright fails. In the first example wrapping with Router removes this 'prototype' error.

But either way nothing is working so far.

I'm getting to the point where I truly feel Enzyme Shallow is broken these days. It's like it can't handle anything anymore like it used to.

You need one dive per HOC, and from another issue you filed, InterviewContainer has two - so you need either 2 or 3 dives here.

right and above I tried that.

When you wrap with Router, you need 3 dives. Your examples above:

  • wrapped with Router, 2 dives, need 3
  • using wrappingComponent, 1 dive, need 2

yea and again above is showed I tried that first:

const interview = interviewContainer.dive().dive().find(".ft-interview");
const interview = interviewContainer.dive().dive().dive().find(".ft-interview");

Both give me Error: ShallowWrapper::dive() can only be called on components

Only one dive allows it to run without completely failing on me to give me at least an assertion error.

And second example
it's bombing out completely with the wrappingComponent: Router so it doesn't even get to diving.

Let's focus on the wrapping example then (not the wrappingComponent one). What do interviewContainer.debug(), interviewContainer.dive().debug(), and interviewContainer.dive().dive().debug() print out?

Note that .dive() only works when the component directly renders a custom component - ie, not a div wrapping a custom component, for that you have to use .find + .shallow instead of .dive.

I'm going to dup my comment to there, see you over in that issue but it seems like you're trying to say the same thing for the same issue I'm having here

Thanks, I've got a lot of enzyme notifications and it's tough to keep them straight :-) let's continue over there.

yea sorry I'm probably not helping with that either. Thx. I'll try to be better about it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amcmillan01 picture amcmillan01  路  3Comments

modemuser picture modemuser  路  3Comments

aweary picture aweary  路  3Comments

andrewhl picture andrewhl  路  3Comments

heikkimu picture heikkimu  路  3Comments