Skip to content
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

Using next-router-mock with class based components #19

Closed
kiuka opened this issue Sep 22, 2021 · 5 comments
Closed

Using next-router-mock with class based components #19

kiuka opened this issue Sep 22, 2021 · 5 comments

Comments

@kiuka
Copy link

kiuka commented Sep 22, 2021

Hello,

I'm trying to use next-router-mock to test class based components which are using withRouter().

My components looks like this:

import React from 'react'
import Head from 'next/head'
import {connect} from 'react-redux'
import {withRouter} from 'next/router'
import {WithRouterProps} from 'next/dist/client/with-router'

import {IRootState} from '../../store'

interface Props extends WithRouterProps {
}

interface State {
}

class View extends React.Component<Props, State> {
  render() {
    return (
      <div>
        <Head>
          <title>...</title>
        </Head>
      </div>
    )
  }
}

const mapStateToProps = (state: IRootState) => ({})

const mapDispatchToProps = {}

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(View))

And my test looks like this:

import mockRouter from 'next-router-mock'
import configureStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import renderer from 'react-test-renderer'
import {Provider} from 'react-redux'

import View from './View'

jest.mock('next/router', () => require('next-router-mock'))
jest.mock('next/dist/client/router', () => require('next-router-mock'))

const middlewares = [thunk]
const mockStore = configureStore(middlewares)

describe('View', () => {
  test('should match snapshot', () => {
    mockRouter.push('/xxx')

    const store = mockStore({...})

    const component = renderer.create((
      <Provider store={store}>
        <View/>
      </Provider>
    ))

    let tree = component.toJSON()

    expect(tree).toMatchSnapshot()
  })
})

When I try to run it, it fails:

 FAIL  View.test.tsx
  ● Test suite failed to run

    TypeError: (0 , _router.withRouter) is not a function

As I see there is no reference of withRouter() in the next-router-mock source, so I guess it does not support this.

Can you help me with any workaround? I guess I have to write my own mock code of withRouter() ? Or can you please implement this?

Thank you!

@scottrippey
Copy link
Owner

You're correct, I have not implemented the withRouter method. However, I do think it would be pretty trivial to implement this, so I'll give it a shot :)
Thank you for the example use-case!

@kiuka
Copy link
Author

kiuka commented Sep 22, 2021

@scottrippey thank you for your quick answer and to taking care of it! Meanwhile I have sort of copied the code from next/router to make it work, it looks like this now, maybe it can help you as well (probably much less code without types:) ):

jest.mock('next/router', () => {
  const router = require('next-router-mock')

  return {
    __esModule: true,
    default: router,
    withRouter<P extends WithRouterProps, C = NextPageContext>(
      ComposedComponent: NextComponentType<C, any, P>
    ): React.ComponentType<ExcludeRouterProps<P>> {
      function WithRouterWrapper(props: any): JSX.Element {
        return <ComposedComponent router={router.useRouter()} {...props} />
      }

      WithRouterWrapper.getInitialProps = ComposedComponent.getInitialProps
      // This is needed to allow checking for custom getInitialProps in _app
      ;(WithRouterWrapper as any).origGetInitialProps = (
        ComposedComponent as any
      ).origGetInitialProps
      if (process.env.NODE_ENV !== 'production') {
        const name = ComposedComponent.displayName || ComposedComponent.name || 'Unknown'
        WithRouterWrapper.displayName = `withRouter(${name})`
      }

      return WithRouterWrapper
    },
  }
})

@scottrippey
Copy link
Owner

Implemented in #20 👍

@scottrippey
Copy link
Owner

Fixed in 0.5.2

@kiuka
Copy link
Author

kiuka commented Sep 23, 2021

You are the best, thank you very much!!

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants