0

I'm working on a legacy JS web project that doesn't use import/require etc. So if I want to write tests, I need to somehow load all the code before the test is executed (I'm using a custom testEnvironment for that).

I've created a sample repo here.

Here are the main files:

// ./src/index.js
function spyOnMe() {
  return "Hello World!";
}

function main() {
  const text = spyOnMe();
  return text;
}
// ./src/index.spec.js
it('should spyOn spyOnMe', () => {
  const mockedValue = 'Thanks for helping!';
  jest.spyOn(window, 'spyOnMe').mockReturnValue(mockedValue);
  expect(spyOnMe()).toBe(mockedValue); // OK
  const result = main();
  expect(result).toBe(mockedValue); // KO
});
// ./jest.config.js
module.exports = {
  clearMocks: true,
  coverageProvider: "v8",
  testEnvironment: "./jest.env.js",
};
// ./jest.env.js
const JSDOMEnvironment = require("jest-environment-jsdom");
const vm = require("vm");
const fs = require("fs");

class MyEnv extends JSDOMEnvironment.default {
  constructor(config, context) {
    super(config, context);
    this.loadContext();
  }

  loadContext() {
    const js = fs.readFileSync("./src/index.js", "utf8");
    const context = vm.createContext();
    context.document = this.global.document;
    context.window = this.global.window;
    vm.runInContext(js, context, {
      filename: "./src/index.js",
      displayErrors: true,
    });
    Object.assign(this.global, context);
  }
}

module.exports = MyEnv;

The issue is in the index.spec.js:

  1. The first expect returns Thanks for helping!
  2. The second one returns "Hello world!"

Why is that?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Gpack
  • 1,878
  • 3
  • 18
  • 45
  • Does this answer your question? [How to mock functions in the same module using Jest?](https://stackoverflow.com/questions/45111198/how-to-mock-functions-in-the-same-module-using-jest) – jonrsharpe Jan 17 '23 at 09:57
  • I don't think so. The problem is there is no import/export/require etc. in the source code and because of its size, migrating all of it would take too much time. So I'm not sure how this would apply here. I'm already loading all the code in the global environment in `jest.env.js`. – Gpack Jan 17 '23 at 10:33

1 Answers1

1

I found a fix but I don't really understand why it works:

In jest.env.js, I should replace this line:

- const context = vm.createContext();
+ const context = vm.createContext(this.global);
Gpack
  • 1,878
  • 3
  • 18
  • 45