kHRISl33t / runtime-env-cra

Runtime environment handler for create-react-apps
MIT License
49 stars 23 forks source link

Add documentation for usage in testing #14

Open AntonyFagundez opened 2 years ago

AntonyFagundez commented 2 years ago

Hi! thanks again for the amazing library.

I was using it and I finded some problems to use in jest with react-testing-library.

To asegurate the app works well i'ts necesary add a property to a window object.

Object.defineProperty(window, "__RUNTIME_CONFIG__", {
    writable: true,
    value: {
      REACT_APP_URL_API: process.env.REACT_APP_URL_API,
      // all the variables that you need in your app
    },
  });

And to works well in any test I abstracted this to a function and added in before all in every test suite

//test-utils.js

export const initEnvironmentVariables = () => {
    Object.defineProperty(window, "__RUNTIME_CONFIG__", {
        writable: true,
        value: {
          REACT_APP_URL_API: process.env.REACT_APP_URL_API,
          // all the variables that you need in your app
        },
     });
}
//example.test.js
import { initEnvironmentVariables  } from "./test-utils";

describe("example", () => {
    beforeAll(()+>{
        initEnvironmentVariables();
    });

    //all your tests
})
seanblonien commented 2 years ago

For create-react-app framework builds, I use this file structure (replace .ts with .js if you're not using TypeScript)

└── public/
    ├── runtime-env.js
└── src/
    ├── setupTests.ts

with this in setupTests.ts (that I believe is auto-generated by the framework on init)

// Because run-time environment variables are dynamically loaded by index.html,
// we need to manually load them into the test environment.
import '../public/runtime-env.js';

Regardless if you're using CRA, this general pattern applies to any usage of the Jest framework if you use the setupFiles configuration.

AntonyFagundez commented 2 years ago

Much better! Best approach! Thanks for sharing!!!

ZukkyBaig commented 2 years ago

Hi, I was having issues with my jest tests (react framework is using CRA), and the setupTests.js solution above worked. However, in my package.json, I have this set in the test section of scripts:

"test": "cross-env NODE_ENV=development runtime-env-cra --config-name=./public/runtime-env.js && craco test --watchAll=false"

Jest automatically sets NODE_ENV=test, but because of this, runtime-env-cra tries to pickup env vars from the host environment, instead of populating it from the .env file (like the NODE_ENV=development behaviour). I think changing the NODE_ENV to development for the Jest tests isn't a good approach, and it is probably best to stick to the recommended approach of NODE_ENV=test.

What should I do in this case? Runtime-env-cra doesn't work when NODE_ENV is set to test.

seanblonien commented 2 years ago

@ZukkyBaig couldn't you just set the two different NODE_ENV's before running the two different scripts?

"test": "cross-env NODE_ENV=development runtime-env-cra --config-name=./public/runtime-env.js && cross-env NODE_ENV=test craco test --watchAll=false"

also, I break out the runtime-env-cra command into its own script to make re-using it from multiple commands (i.e. your npm start and npm test scripts both use it), which makes it a little cleaner with more separation of concern too. i do this by either just doing both commands in one script, or by using "pre" scripts

"env": "cross-env NODE_ENV=development runtime-env-cra --config-name ./public/runtime-env.js",

"test": "npm run env && cross-env NODE_ENV=test craco test --watchAll=false",
// OR
"pretest": "npm run env",
"test": "cross-env NODE_ENV=test craco test --watchAll=false",
kHRISl33t commented 2 years ago

@seanblonien if you have time for it, can you add some docs about testing use cases?