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?
Note: In order to mock properly, Jest needs jest. mock('moduleName') to be in the same scope as the require/import statement. Here's a contrived example where we have a module that provides a summary of all the files in a given directory. In this case, we use the core (built in) fs module.
To mock a Node module with Jest, we can use the jest. createMockFromModule method. const utils = jest. createMockFromModule('../utils').
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With