Skip to content

Testing components which use a fetcher does not work with createRemixStub #7776

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

Open
1 task done
KnisterPeter opened this issue Oct 26, 2023 · 1 comment
Open
1 task done

Comments

@KnisterPeter
Copy link
Contributor

What version of Remix are you using?

2.1.0

Are all your remix dependencies & dev-dependencies using the same version?

  • Yes

Steps to Reproduce

Create a simple remix app with a component using useFetcher.
Then write a test case using createRemixStub to test that component.

Expected Behavior

The component should render and eventually receive the loader data from the fetcher.

Actual Behavior

The initial state is rendered, the loader is called, but the loader data never reaches the fetcher.
The component is not re-rendered and the test fails.

@Tyrannogyna
Copy link

Tyrannogyna commented Jan 23, 2025

I'm experiencing this same problem but the thing is it was working before, and it stopped working when I deleted package-lock and did a fresh install. None of the packages in package.json changed, just minor versions of a bunch of other packages.

When I debug my test, the debugger:

  1. stops first at the useEffect when rendering the component. In here, fetcher.data is empty.
useEffect( () => {
        if (fetcher.data) {
            const data = fetcher.data as ParsedEvents;
            let updatedPools: PoolData[] = [];
            for (const pool of loaderPools) {
                if (pool.name === data.poolName) {
                    updatedPools.push({ ...pool, events: { ongoing: data.ongoing, today: data.today, tomorrow: data.tomorrow } });
                } else {
                    updatedPools.push({ ...pool })
                }
            }
            setPools(updatedPools)
        }
    }, [fetcher.data, loaderPools]);
  1. Then the test clicks on a component which triggers
    function handleRowExpand(poolId: string | number | bigint | object) {
        fetcher.load(`/edge-pools/${poolId}/events`)
    }
  1. When using the real loader on the test but mocking the endpoints, the loader in route /edge-pools/${poolId}/events is called and the return values are correct.
  2. Test fails. useEffect doesn't run again with the updated value from fetcher.

This was not the behaviour of the tests before the update to package-lock.json, nor is the behaviour when the page runs, the fetcher works correctly, useEffect is called with the correct value. I tried adding a timeout to the test to give it more time, in case the second call to useEffect was being slower than the test, but it doesn't change this.

This are the package.json dependencies:

"dependencies": {
        "@prisma/client": "^5.5.2",
        "@remix-run/node": "^2.11.2",
        "@remix-run/react": "^2.11.2",
        "@remix-run/serve": "^2.11.2",
        "@remix-run/testing": "^2.11.2",
        "@testing-library/jest-dom": "^6.5.0",
        "@testing-library/react": "^16.0.0",
        "express": "^4.18.2",
        "i18next": "^23.7.16",
        "i18next-browser-languagedetector": "^7.2.0",
        "i18next-fs-backend": "^2.3.1",
        "i18next-http-backend": "^2.4.2",
        "isbot": "^3.7.0",
        "jose": "^5.3.0",
        "openid-client": "^5.6.5",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "react-i18next": "^14.0.0",
        "remix-i18next": "^5.5.0",
        "tiny-invariant": "^1.3.1",
        "internal-ui-components": "2.2.1"
    },
    "devDependencies": {
        "@babel/core": "^7.23.7",
        "@babel/preset-env": "^7.23.7",
        "@babel/preset-react": "^7.23.3",
        "@jest/globals": "^29.7.0",
        "@remix-run/dev": "^2.11.2",
        "@remix-run/eslint-config": "^2.11.2",
        "@stylistic/eslint-plugin": "^2.4.0",
        "@testing-library/user-event": "^14.5.2",
        "@types/eslint": "^8.44.6",
        "@types/jest": "^29.5.11",
        "@types/node": "^20.8.10",
        "@types/react": "^18.2.33",
        "@types/react-dom": "^18.2.14",
        "babel-jest": "^29.7.0",
        "dotenv-cli": "^7.4.1",
        "eslint": "^8.52.0",
        "eslint-plugin-jest-dom": "^5.1.0",
        "eslint-plugin-testing-library": "^6.2.0",
        "isomorphic-fetch": "^3.0.0",
        "jest": "^29.7.0",
        "jest-environment-jsdom": "^29.7.0",
        "jest-mock-extended": "^3.0.7",
        "jest-sonar": "^0.2.16",
        "jose": "^5.3.0",
        "msw": "^2.3.0",
        "prisma": "^5.5.2",
        "ts-jest": "^29.1.1",
        "ts-node": "^10.9.1",
        "typescript": "^5.2.2"
    },

The update to package-lock.json seems to have installed @remix-run 2.15.2 version. ts-jest is version 29.2.5, jest is the same version. I tried forcing v2.11.2 and it does not seem to make any difference, so the error must be in some other dependency version, but I have not figured out which one as I don't understand the inner workings of createRemixStub

This is how I create the remix stub, which, as I said, worked with previous package-lock:

const Stub = createRemixStub([
            {
                Component() {
                    return (
                        <I18nextProvider i18n={i18nInstance}>
                            <Outlet/>
                        </I18nextProvider>
                    );
                },
                children: [{
                    Component: PopLayout,
                    children: [
                        {
                            path: "/edge-pools",
                            Component: EdgePoolsListPage,
                            loader: () => {
                                return json([popPoolsList[0]]);
                            }
                        },
                        {
                            path: "/edge-pools/1/events",
                            loader: () => { return json(parsedEvents) }
                        }
                    ]
                }]
            }]);
        render(<Stub initialEntries={["/edge-pools"]} />);

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

No branches or pull requests

3 participants