简体   繁体   中英

How to mock DataTransfer with Jest

I have some React components where I use the HTML Drag interface .

In particular, I listen to dragover events on one component and set x and y positions with the DataTransfer object. Then, I listen to dragleave events on a different component and retrieve x and y positions from the DataTransfer.

I'm using Jest and Enzyme to test my components.

If I run my tests I get this error:

Test suite failed to run
ReferenceError: DataTransfer is not defined

As far I understand, the Drag interface is not available in Jest, so I need to mock it and (maybe?) make it available via Jest globals .

For now I defined DataTransfer in my jest.config.js and made it a global, but I'm not sure if this is the best solution.

class DataTransfer {
  constructor() {
    this.data = { dragX: "", dragY: "" };
    this.dropEffect = "none";
    this.effectAllowed = "all";
    this.files = [];
    this.img = "";
    this.items = [];
    this.types = [];
    this.xOffset = 0;
    this.yOffset = 0;
  }
  clearData() {
    this.data = {};
  }
  getData(format) {
    return this.data[format];
  }
  setData(format, data) {
    this.data[format] = data;
  }
  setDragImage(img, xOffset, yOffset) {
    this.img = img;
    this.xOffset = xOffset;
    this.yOffset = yOffset;
  }
}

const baseConfig = {
  globals: {
    DataTransfer: DataTransfer,
  },
  // other config...
};

module.exports = baseConfig;

What is the best way to mock the Drag interface in Jest?

I am using following custom mockup:

  // Arrange

  // Map as storage place
  const testStorage = new Map();

  // Mock of the drop Event
  const testEvent = {
      dataTransfer: {
        setData: (key, value) => testStorage.set(key, value),
        getData: (key) => testStorage.get(key)
      }
    };
    // remmeber to have 'and.callTrough()' to allow go trough the method
    spyOn(testEvent.dataTransfer, 'getData').and.callThrough();

    // Act
    // Add your code here

    // Assert
    expect(testEvent.dataTransfer.getData('YOUR_CHECKED_KEY')).toEqual('EXCPECTED_VALUE');

It's important to know that in these cases, you do not really need to follow the "best" way of mocking the API, because there just isn't one. Mocking an API is just about giving your script the environment it needs to be executed, so it would have relevant input and output. If the mock you've made serves its purpose, then there's absolutely no need to look for a better way You're creating a class definition for your DataTransfer mock. That's the way we usually make mocks. So I guess yours is a good solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM