Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking `document` in jest

I'm trying to write tests for my web components projects in jest. I already use babel with es2015 preset. I'm facing an issue while loading the js file. I have followed a piece of code where document object has a currentScript object. But in test context it is null. So I was thinking of mocking same. But jest.fn() is not really help in same. How can I handle this issue?

Piece of code where jest is failing.

var currentScriptElement = document._currentScript || document.currentScript; var importDoc = currentScriptElement.ownerDocument; 

Test case I have written. component.test.js

import * as Component from './sample-component.js';  describe('component test', function() {   it('check instance', function() {     console.log(Component);     expect(Component).toBeDefined();   }); }); 

Following is the error thrown by jest

Test suite failed to run      TypeError: Cannot read property 'ownerDocument' of null        at src/components/sample-component/sample-component.js:4:39 

Update: As per suggestion from Andreas Köberle, I have added some global vars and tried to mock like following

__DEV__.document.currentScript = document._currentScript = {   ownerDocument: '' }; __DEV__.window = {   document: __DEV__.document } __DEV__.document.registerElement = jest.fn();  import * as Component from './arc-sample-component.js';  describe('component test', function() {   it('check instance', function() {     console.log(Component);     expect(Component).toBeDefined();   }); }); 

But no luck

Update: I have tried above code without __dev__. Also by setting document as global.

like image 542
thecodejack Avatar asked Dec 12 '16 09:12

thecodejack


People also ask

How do you do mocking in Jest?

Mocking Modules​ export default Users; Now, in order to test this method without actually hitting the API (and thus creating slow and fragile tests), we can use the jest. mock(...) function to automatically mock the axios module.

What is __ mocks __ in Jest?

Mocking Node modules​ If the module you are mocking is a Node module (e.g.: lodash ), the mock should be placed in the __mocks__ directory adjacent to node_modules (unless you configured roots to point to a folder other than the project root) and will be automatically mocked. There's no need to explicitly call jest.

What is Jsdom Jest?

jsdom is a pure JavaScript implementation of the DOM and browser APIs that runs in node. If you're not using Jest and you would like to run your tests in Node, then you must install jsdom yourself. There's also a package called global-jsdom which can be used to setup the global environment to simulate the browser APIs.


2 Answers

Similar to what others have said, but instead of trying to mock the DOM yourself, just use JSDOM:

// __mocks__/client.js  import { JSDOM } from "jsdom" const dom = new JSDOM() global.document = dom.window.document global.window = dom.window 

Then in your jest config:

    "setupFiles": [       "./__mocks__/client.js"     ], 
like image 51
Patrick Lee Scott Avatar answered Sep 18 '22 14:09

Patrick Lee Scott


I have resolved this using setUpFiles property in jest. This will execute after jsdom and before each test which is perfect for me.

Set setupFiles, in Jest config, e.g.:

"setupFiles": ["<rootDir>/browserMock.js"]   // browserMock.js Object.defineProperty(document, 'currentScript', {   value: document.createElement('script'), }); 

Ideal situation would be loading webcomponents.js to polyfill the jsdom.

like image 40
thecodejack Avatar answered Sep 19 '22 14:09

thecodejack