1

I am unit testing a React/Typescript component with Jest and React Testing Library and running into this error: SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse.

I understand that you get this error when you try to do JSON.parse(undefined). I am trying to figure out why this is happening in my test.

The test routes to the /new route where the NewPage component is rendered then the error is thrown when it hits this line const state = JSON.parse(JSON.stringify(location.state)) (see component below).

It seems like this has to be mocked somehow in Jest but not sure how to go about doing this.

test

test('AppRouter should navigate to /new', () => {
    window.history.pushState({}, '', '/new')
    render(
        <BrowserRouter>
            <AppRouter />
        </BrowserRouter>
    )
})

Error: error

Component that is throwing the error:

import { useEffect, useContext } from 'react'
import { useHistory, useLocation } from 'react-router-dom'
import { observer } from 'mobx-react-lite'

import UserContext from '../../context/User'
import PostContext from '../../context/Post'
import WritingField from '../../components/writingField/writingField'
import BasicPage from '../basicPage/basicPage'
import { DataType } from '../../constants'

const NewPage = () => {
    const history = useHistory()
    const location = useLocation<Location>()
    const state = JSON.parse(JSON.stringify(location.state))
    const isConfirmed = state.isConfirmed
    const userContext = useContext(UserContext)
    const postContext = useContext(PostContext)

    useEffect(() => {
        console.log('Is this new page being confirmd? ' + isConfirmed)
    }, [])

    const preventPropagation = (event: any) => {
        event.stopPropagation()
    }

    const submit = async (
        title: string,
        content: string,
        epkNonce: number,
        reputation: number
    ) => {
        if (!userContext.userState) {
            throw new Error('Should not be able to create post without login')
        }
        postContext.publishPost(title, content, epkNonce, reputation)
        history.push('/')
    }

    return (
        <BasicPage>
            <h3>Create post</h3>
            <WritingField
                type={DataType.Post}
                submit={submit}
                submitBtnName="Post - 5 points"
                onClick={preventPropagation}
            />
        </BasicPage>
    )
}

export default observer(NewPage)

It should also be noted that I am not rendering this component directly; it is being navigated to from my router component. I do not believe this is the cause of the issue though.

Thanks.

EDIT:

I am trying to currently mock out the location and history hooks that the component uses and have tried this code which throws the same error but may be getting closer:

const mockHistoryPush = jest.fn();
jest.mock('react-router-dom', () => ({
    ...jest.requireActual('react-router-dom'),
    useHistory: () => ({
        push: mockHistoryPush,
    }),
    useLocation: () => ({
        pathname: "/"
    })
}));
AAMCODE
  • 415
  • 1
  • 7
  • 20

1 Answers1

0

Looks like I was on the right path with the mock I was implementing.

The error stemmed from the location.state being undefined (which it was) so that is why the mock is needed.

Simple configuring the location mock to have a value to not make JSON parse an undefined value stopped the error from being thrown.

Here is the code:

// mock needed for history and location hooks
const mockHistoryPush = jest.fn();

jest.mock('react-router-dom', () => ({
    ...jest.requireActual('react-router-dom'),
    useHistory: () => ({
        push: mockHistoryPush,
    }),
    useLocation: () => ({
        state: {
            test: {
                test: "test",
            }
        }
    })
}));

AAMCODE
  • 415
  • 1
  • 7
  • 20