How to I access my .env variables from a vitest test?
Asked Answered
S

9

22

I am trying to migrate my tests from jest to vitest. I have a test suite that uses the dotenv package to pull in my .env variables.

I have this in my test suite

beforeAll(async () => {
        vi.clearAllMocks();
        cleanUpMetadata();
        dotenv.config();
        controller = new UserController(container.get<UserServiceLocator>(Symbol.for("UserServiceLocator")),
            container.get<EmailServiceLocator>(Symbol.for("EmailServiceLocator")));
    });

and this is the code in the test that has the undefined variable

let requestObj = httpMocks.createRequest({
            cookies: {
                token: jwt.sign({ username: "testusername" }, process.env.JWT_SECRET_KEY!)
            }
        });

Is there something special to vitest that i have to do in order to get my .env variables to be accessible?

Sammysamoan answered 9/7, 2022 at 19:46 Comment(0)
C
26

You can include the dotenv package(if thats what you are using) into the vitest.config.ts file, it will look something like this below:

import { defineConfig } from 'vitest/config';
import { resolve } from 'path';

export default defineConfig({
  root: '.',
  esbuild: {
    tsconfigRaw: '{}',
  },
  test: {
    clearMocks: true,
    globals: true,
    setupFiles: ['dotenv/config'] //this line,
  },
  resolve: {
    alias: [{ find: '~', replacement: resolve(__dirname, 'src') }],
  },
});
Confront answered 18/12, 2022 at 6:40 Comment(6)
this works, this should be the accepted answer in 2024 – Dian
why we need dotenv? node already can read .env – Incontrollable
@Incontrollable Node 20 was released after this answer was written πŸ™‚ – Mauser
@Mauser so what's the recommended way to perform this task using Node.js 20? – Lagunas
@RobinBozan Node 20 support requires passing a --env-file when running node so if you don't have the ability to do that, stick with the dotenv package as this comment suggests – Mauser
@Mauser I understand but the command to run vitest is vitest, not node. I found some relevant discussion here: github.com/vitest-dev/vitest/issues/5756 – Lagunas
F
3

I use the vite loadEnv function in vitest.config.ts and that works:

import { defineConfig } from 'vitest/config'
import { loadEnv } from 'vite'

export default defineConfig({
    test: {
        environment: 'jsdom',
        env: loadEnv('', process.cwd(), ''),
    },
})
Ferrara answered 19/2 at 12:30 Comment(1)
if you want to load .env.test for testing only and not affecting production mode you have to use loadEnv('test', process.cwd(), '') – Ldopa
M
3

I know this question is quite old, but my workaround to this was parsing my .env file inside vitest.config:

import { config } from "dotenv";
import tsconfigPaths from "vite-tsconfig-paths";
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    passWithNoTests: true,
    globals: true,
    coverage: {
      provider: "v8",
      exclude: ["**/tests/**"],
    },
    env: {
      ...config({ path: "./env/.testing.env" }).parsed,
    },
  },
  plugins: [tsconfigPaths()],
});

This allows me to have multiple config files using mergeConfig from Vitest in case of multiple testing environments.

If I'm not wrong you can also do this by setting up setup and teardown functions as a global setup files.

export async function setup() {
  // LOAD .ENV HERE
  app.listen(env.PORT, () => {
    console.log("Started testing server...");
  });
}

export async function teardown() {
  await app.stop();
}
Methadone answered 22/3 at 13:25 Comment(0)
V
2

If you are using dotEnv

  1. Load the env with config()/dotenv.config() up to you
  2. point the your envs in the config
import { defineConfig } from 'vitest/config'
import { config } from 'dotenv'
//#1
config()

export default defineConfig({
  test: {
    ...
   //#2
    env: process.env,
    ...
  }
})
Vasomotor answered 15/5 at 15:39 Comment(0)
P
0
import.meta.env.%VARIABLE_NAME%

Got it from here: https://stackoverflow.com/a/70711231

Pishogue answered 24/8, 2022 at 8:45 Comment(0)
H
0

In Node.js Assuming you want to access your env variable VAR you should prefix it with VITE_ like:

VITE_VAR=123

then you can access it regularly with process.env.VITE_VAR

Hohenlinden answered 9/4, 2023 at 12:54 Comment(3)
Do you have a link to an official documentation stating this ? – Barnette
@Barnette - here: vitejs.dev/guide/env-and-mode.html#env-files – Hohenlinden
Oh ok I see. But that's not what OP is asking. They want to access their "business code" env variable. Therefore, they won't rename JWT_SECRET_KEY to VITE_JWT_SECRET_KEY. Instead, they need to inject the actual env vars into Vite so their function has them available without even knowing it's being executed by Vite (see my answer below). – Barnette
B
0

Load environment variables

  • This example is work next.js but should work aswell with dotenv
  • vitest.config.ts
// ==== VITEST ====
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import tsconfigPaths from 'vite-tsconfig-paths'

// ==== NEXT.JS ====
import { loadEnvConfig } from '@next/env'
loadEnvConfig(process.cwd())

export default defineConfig({
    plugins: [tsconfigPaths(), react()],
    test: {
        environment: 'node',
        globalSetup: 'test/setup-tests.ts'
    }
})
  • environment must be node. jsdom will not work
Broch answered 22/6 at 22:36 Comment(0)
B
0

For whoever lands here after removing the dotenv lib because Node v20.6.0+ handles .env files automatically, just use the loadEnv function from vite in your vitest.config.ts:

export default defineConfig(({ mode }) => ({
    test: {
        env: loadEnv(mode, process.cwd(), ''),
    },
}));

Provided you use a default .env file.

Barnette answered 27/7 at 19:38 Comment(0)
S
-1

vitest will automatically load your .env file(s) from the project root directory, which probably isn't the same directory as your test files. Your file structure might look something like this:

πŸ— project
  πŸ–Ή .env
  πŸ–Ή package.json
  πŸ–Ή vite.config.json
  πŸ— src/
    πŸ–Ή myCode.js
  πŸ— test/
    πŸ–Ή myCode.test.js

In node, you access a variable using import.meta.env.VITE_MY_VARIABLE_NAME. In HTML, use the special syntax %VITE_MY_VARIABLE_NAME%.

If you're still getting undefined variables, add the VITE_ prefix to your variable name, which tells vite the value is safe to expose.

Shaer answered 13/7, 2023 at 4:52 Comment(2)
doesn't work...... – Hepcat
no, VITE_ is only for the client, not tests – Incontrollable

© 2022 - 2024 β€” McMap. All rights reserved.