Lusito / mockzilla

A mocking toolkit leveraging the power of TypeScript to enhance your jest experience.
https://lusito.github.io/mockzilla/
zlib License
14 stars 2 forks source link

Property `browser.storage.onChanged` is not defined #6

Closed reccanti closed 4 years ago

reccanti commented 4 years ago

Hello! Right now, I'm trying to get Mockzilla working with my extension's unit tests. I have a class with a constructor function like this:

// dataManager.ts

export class DataManager {
  private tabId: string;
  private windowId: string;
  private changeCallbacks: Set<ChangeCallback> = new Set();

  constructor(
    tabId: string,
    windowId: string
  ) {
    this.tabId = tabId;
    this.windowId = windowId;
    browser.storage.onChanged.addListener(this.listen);
  }

  // ...
}

I'm currently trying to set up my unit tests and mocks like this:

// dataManager.test.ts

import {difference, calculateChanges, DataManager} from '@root/dataManager';
import type {Browser} from 'webextension-polyfill-ts';
import {deepMock, MockzillaDeep, mockAssimilate} from 'mockzilla';
import {ComponentData} from '@root/contentScripts/gatherComponentData';

const [browser, mockBrowser, mockBrowserNode] = deepMock<Browser>(
  'browser',
  false
);
jest.doMock('webextension-polyfill-ts', () => ({browser}));

// ...

describe('DataManager', () => {
  beforeEach(() => mockBrowserNode.enable());
  afterEach(() => mockBrowserNode.verifyAndDisable());

  it('responds to changes to component data', () => {
    const listen = jest.fn();
    mockBrowser.storage.onChanged.addListener.expect(listen, expect.anything());

    const manager = new DataManager('1', '2');
    const cb = jest.fn();
    manager.addChangeListener(cb);
  });

});

However, I get the following error:

 ● DataManager › responds to changes to component data

    TypeError: Cannot read property 'onChanged' of undefined

      55 |     this.tabId = tabId;
      56 |     this.windowId = windowId;
    > 57 |     browser.storage.onChanged.addListener(this.listen);
         |                     ^
      58 |   }
      59 | 
      60 |   /**

      at new DataManager (src/dataManager/index.ts:57:21)
      at Object.it (src/dataManager/__tests__/index.test.ts:104:21)

When I try to log browser, all I see is an empty object. Any idea why this might be happening? Is it something to do with the doMock call, my class, or is it something else entirely?

Thanks!

Lusito commented 4 years ago

Hi,

if you want to test webextensions, I'd recommend to use https://lusito.github.io/mockzilla-webextension/.

Still, it should work with mockzilla itself as well. Check the following:

reccanti commented 4 years ago

Thanks for getting back to me so quickly! I figured out the issue, I had an existing, incomplete jest mock for the "browser" that was interfering with the mock creation 😅. Deleting it seemed to fix the issue.

mockzilla-webextenion is just what I need, so I've switched over to that. Thanks for your help!