typescriptjestjsjsdom

document.body.innerHTML set in JSDOM ignored by implementation


Here is my TS code:

export class MyClass {
  private myElement: HTMLElement;
  constructor() {
    this.myElement = document.getElementById("ID") as HTMLElement;
    if (!this.myElement) {
      throw new Error("myElement is missing")
    }
  }
}

Here is my Jest test:

it("should not throw an error", () => {
  document.body.innerHTML = "<div id='ID'>some text</div>";
  const sut = new MyClass();
});

Here is my jest.config.js:

module.exports = {
  preset: "ts-jest",
  testEnvironment: "jsdom"
}

My package.json:

{
...
"scripts": {
  "test": "jest"
},
"devDependencies": {
  "@types/jest": "^29.5.12",
  "jest": "^29.7.0",
  "jest-environment-jsdom": "^29.7.0",
  "ts-jest": "^29.1.2",
  "ts-loader": "^9.5.1",
  "typescript": "^5.4.2",
  "webpack": "^5.90.3",
  "webpack-cli": "^5.1.4"
}
}

For some reason, the div I create in my unit test seems to be ignored and the implementation throws an error: "myElement is missing".

Can anyone spot the issue with my setup? Thank you in advance!


Solution

  • Unable to reproduce. Your code works fine for me on Ubuntu 22.04, assuming I import the file:

    t.test.ts:

    import { MyClass } from "./t";
    
    it("should not throw an error", () => {
      document.body.innerHTML = "<div id='ID'>some text</div>";
      const sut = new MyClass();
      expect(document.querySelector("#ID").textContent).toBe("some text");
    });
    

    t.ts:

    export class MyClass {
      private myElement: HTMLElement;
      constructor() {
        this.myElement = document.getElementById("ID") as HTMLElement;
        if (!this.myElement) {
          throw new Error("myElement is missing")
        }
      }
    }
    

    package.json:

    {
      "scripts": {
        "test": "jest"
      },
      "devDependencies": {
        "@types/jest": "^29.5.12",
        "jest": "^29.7.0",
        "jest-environment-jsdom": "^29.7.0",
        "ts-jest": "^29.1.2",
        "ts-loader": "^9.5.1",
        "typescript": "^5.4.2",
        "webpack": "^5.90.3",
        "webpack-cli": "^5.1.4"
      }
    }
    

    jest.config.js:

    module.exports = {
      preset: "ts-jest",
      testEnvironment: "jsdom"
    }
    

    Run:

    $ npm i
    $ npm run test
    
    > test
    > jest
    
    ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
     PASS  ./t.test.ts
      ✓ should not throw an error (11 ms)
    
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        1.072 s
    Ran all test suites.