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

Closed
1 task done
KnisterPeter opened this issue Oct 26, 2023 · 2 comments
Closed
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"]} />);

@brophdawg11
Copy link
Contributor

Thank you for opening this issue, and our apologies we haven't gotten around to it yet!

With the release of React Router v7 we are sun-setting continued development/maintenance on Remix v2. If you have not already upgraded to React Router v7, we recommend you do so. We've tried to make the upgrade process as smooth as possible with our Future Flags. We are now in the process of cleaning up outdated issues and pull requests to improve the overall hygiene of our repositories.

We plan to continue to address 2 types of issues in Remix v2:

  • Bugs that pose security concerns
  • Bugs that prevent upgrading to React Router v7

If you believe this issue meets one of those criteria, please respond or create a new issue.

For all other issues, ongoing maintenance will be happening in React Router v7, so:

  • If this is a bug, please reopen this issue in that repo with a new minimal reproduction against v7
  • If this is a feature request, please open a new Proposal Discussion in React Router, and if it gets enough community support it can be considered for implementation

If you have any questions you can always reach out on Discord. Thanks again for providing feedback and helping us make our framework even better!

@brophdawg11 brophdawg11 closed this as not planned Won't fix, can't repro, duplicate, stale May 7, 2025
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