How do I test `image.onload` using jest in the context of redux actions (or other callbacks assigned in the action)

谁说胖子不能爱 提交于 2019-12-01 19:21:33

After some investigation, I found a very interesting javascript function that would solve my issue.

It is this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

Here's how I used Object.defineProperty(...) to solve my issue:

describe('fetchInsuranceCardPhoto', () => {
    let imageOnload = null;


    /** Override Image global to save onload setting here so that I can trigger it manually in my test */
    function trackImageOnload() {
        Object.defineProperty(Image.prototype, 'onload', {
            get: function () {
                return this._onload;
            },
            set: function (fn) {
                imageOnload = fn;
                this._onload = fn;
            },
        });
    }

    it('triggers RECEIVED_INSURANCE_CARD_PHOTO when 200 returned with data', async () => {
        trackImageOnload();
        givenAPICallSucceedsWithData();

        await store.dispatch(fetchInsuranceCardPhoto());
        imageOnload();

        expectActionsToHaveBeenTriggered(
            REQUESTING_INSURANCE_CARD_PHOTO,
            RECEIVED_INSURANCE_CARD_PHOTO,
            STORE_CARD_IMAGE_SIZE,
        );
    });

What I did here was use define property to override the setter of any instance of Image. the setter would continue to get or set like normal but would also save the value (in this case a function) that was set to a variable in the scope of the unit test. After which, you can just run that function you captured before the verification step of your the test.

Gotchas - configurable needs to be set - note that defineProperty is a different function than defineProperties - This is bad practice in real code. - remember to use the prototype

Hope this post can help a dev in need!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!