Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use the module when testing in Jest/Enzyme? #50

Open
kevinkuebler opened this issue Feb 27, 2019 · 7 comments
Open

How to use the module when testing in Jest/Enzyme? #50

kevinkuebler opened this issue Feb 27, 2019 · 7 comments

Comments

@kevinkuebler
Copy link

Thanks for this polyfill/ponyfill. I recently discovered the ResizeObserver api and realized it was exactly what I needed to solve a problem in my app. However, I'm having trouble figuring out how to use it in a way that works both in my app and in the tests for my app.

The app is a React app written in TypeScript. I have a component that needs to use ResizeObserver in the componentDidMount lifecycle method, so the module is imported in the component as:
import ResizeObserver from 'resize-observer-polyfill';

And then used in the code like:

const ro = new ResizeObserver((entries, observer) => {...});
ro.observe(...);

Obviously leaving out the specific observer details, but this works great and does exactly what I wanted it to do in my app.

The problem is that any tests we have (the tests are also written in TypeScript using Jest and Enzyme) that mount this component fail with the following when Jest tries to run them:
TypeError: resize_observer_polyfill_1.default is not a constructor.

We tried changing how the module is imported to use the require syntax, like const ResizeObserver = require('resize-observer-polyfill'). This results in the tests working, but then we get the same error in the browser when running the Webpack'ed React app. Is there a way to use this module that will work in both Webpack'ed code in the browser and the Jest tests in Node?

I admit that I still get confused by the various JS module formats and how they interact, so I may just be doing something dumb/wrong here. If there's any more specific information needed about our specific configuration just let me know. The versions of the various libraries involved are (from package.json):

"react": "^16.2.0",
"typescript": "3.1.6",
"webpack": "^3.1.0",
"jest": "^22.4.3",
"resize-observer-polyfill": "^1.5.1"
@IlCallo
Copy link

IlCallo commented Mar 18, 2019

Unluckily, I have the same problem in an Angular app, using Jest as test framework.
No idea about how to fix it, but failures doesn't happen all the times.

Based on #42, it could be a problem with webpack.

@abhishekdev
Copy link

I believe the tests should be mocking the ResizeObserver, however jsdom (i am assuming this as enzyme was mentioned) does not have a implementation of ResizeObserver (esp. because it is related to the rendering logic). I worked around it by mocking the ResizeObserver in my tests.

__mocks__/ResizeObserver.js

class ResizeObserver {
    observe() {
        // do nothing
    }
    unobserve() {
        // do nothing
    }
}

window.ResizeObserver = ResizeObserver;

export default ResizeObserver;

sample.test.js*

import ResizeObserver from './__mocks__/ResizeObserver';
import module from 'sample;

describe('module', ()=> {
     it('returns an instance of ResizeObserver', () => {
           // do something that uses the resize observer
           // NOTE: The actual observe handler would not be called in jsdom anyways as no resize would be triggered.
           // e.g.
           expect(module.somethingThatReturnAReference to the resize observer).toBeInstanceOf(ResizeObserver);
        });
});

I would not be testing the functionality of ResizeObserver in my tests but I have other unit tests to test the handler logic based on mocked entry inputs from ResizeObserver.

@philg-ygt
Copy link

^ this is the approach to use: mock out the basic API (observe, unobserve, disconnect) and use jest.fn() to return particular mock entries in the test.

@oschlegel
Copy link

It can be mocked like this:

jest.mock('resize-observer-polyfill', () => ({
  __esModule: true,
  default: jest.fn().mockImplementation(() => ({
    observe: jest.fn(),
    unobserve: jest.fn(),
    disconnect: jest.fn(),
  })),
}));

@Doenja
Copy link

Doenja commented Dec 21, 2021

This workaround worked for me:

sample.spec.ts

beforeEach(() => {
    Object.defineProperty(global, "ResizeObserver", {
        writable: true,
        value: jest.fn().mockImplementation(() => ({
            observe: jest.fn(() => "Mocking works"),
            unobserve: jest.fn(),
            disconnect: jest.fn(),
        })),
    });
});

@Edgaras318
Copy link

can you give full picture

@rodpatulski
Copy link

I believe the tests should be mocking the ResizeObserver, however jsdom (i am assuming this as enzyme was mentioned) does not have a implementation of ResizeObserver (esp. because it is related to the rendering logic). I worked around it by mocking the ResizeObserver in my tests.

__mocks__/ResizeObserver.js

class ResizeObserver {
    observe() {
        // do nothing
    }
    unobserve() {
        // do nothing
    }
}

window.ResizeObserver = ResizeObserver;

export default ResizeObserver;

sample.test.js*

import ResizeObserver from './__mocks__/ResizeObserver';
import module from 'sample;

describe('module', ()=> {
     it('returns an instance of ResizeObserver', () => {
           // do something that uses the resize observer
           // NOTE: The actual observe handler would not be called in jsdom anyways as no resize would be triggered.
           // e.g.
           expect(module.somethingThatReturnAReference to the resize observer).toBeInstanceOf(ResizeObserver);
        });
});

I would not be testing the functionality of ResizeObserver in my tests but I have other unit tests to test the handler logic based on mocked entry inputs from ResizeObserver.

I have tried this, and it works if my test has a .js or .jsx extension, but does not work when it has a .ts or .tsx extension. It never runs the mocks/ResizeObserver.js file when importing from the test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants