0

I am new at jtest; I want to be able to unit test a function (that normally runs in a browser).

Here's a simple situation where I thought the document was passed to the test function but it is not.

Tested function (in tested_file.js)

    function hello_world() {
        console.log(document.documentElement.outerHTML); 
        //Line above outputs an empty html : <html><head></head><body></body></html>
        //So obviously line below returns null
        return document.getElementById("id1").id;  
    }

    // Export the function for testing purposes
    if (typeof module !== 'undefined' && module.exports) {
         module.exports = {
            hello_world: hello_world,
        };
    }

Testing function

    const { TextEncoder, TextDecoder } = require('text-encoding');
    global.TextEncoder = TextEncoder;
    global.TextDecoder = TextDecoder;

    const jsdom = require("jsdom");
    const { JSDOM } = jsdom;
    const { hello_world } = require("<path>/tested_file.js");

    // mock the HTML structure
    const dom = new JSDOM(`
    <!DOCTYPE html>
    <html>
        <body>
            <img id="id1" src="foo.jpg" />
        </body>
    </html>
    `);

    // Get the window object out of JSDOM
    let window = dom.window;
    let document = window.document;

    global.document = document;
    global.window = window;

    describe('hello_world', () => {
       test('returns correct id', () => {
           var x = hello_world();
           expect(x).toBe("id1")
        });

    });

and package.json

{
  "scripts": {
    "js_test": "jest",
  },
  "jest": {
    "testEnvironment": "jsdom"
  },
  "devDependencies": {
    "jest": "^29.5.0",
    "jest-environment-jsdom": "^29.5.0",
    "jsdom": "^22.0.0",
    "text-encoding": "^0.7.0"
  }
}

I run my test like this

npm run js_test

The test fails because null is returned. I obviously miss how to correctly pass my DOM, any help would be great.

Tried many ways of passing the html like calling this within the test function

document.body.innerHTML =  
<!DOCTYPE html>                    
    <html>                     
        <body>                     
            <img id="id1" src="foo.jpg" />                     
        </body>                     
    </html>;

1 Answers1

0

Nailed it, the final solution is much easier, no need to call jsdom, it's all done under the hood

Working testing function

/**
 * @jest-environment jsdom
 */

const { hello_world } = require("<path>/tested_file.js");

describe('hello_world', () => {
    beforeEach(() => {
        document.body.innerHTML = `
            <!DOCTYPE html>
            <html>
            <body>
                <img id="id1" src="">
            </body>
            </html
        `
    });
    test('returns correct id', () => {
        expect(hello_world()).toBe("id1")
    });
});

also

"jest": {
    "testEnvironment": "jsdom"
  },

not needed in package.json and can be replaced with

/**
 * @jest-environment jsdom
 */

in the test code file