我有一个从视频元素中提取像宽度和高度这样的Meta数据的函数,如下所示:
export async function getVideoMetadata(
videoBlobUrl: string,
videoElement: HTMLVideoElement,
): Promise<{ width: number; height: number }> {
// Trigger video load
return new Promise<{ width: number; height: number }>((resolve, reject) => {
videoElement.onloadedmetadata = () => {
videoElement.width = videoElement.videoWidth;
videoElement.height = videoElement.videoHeight;
videoElement.currentTime = videoElement.duration * 0.25;
};
videoElement.onseeked = () => {
resolve({ width: videoElement.videoWidth, height: videoElement.videoHeight });
};
videoElement.onerror = () => {
reject(`Error loading video`);
};
videoElement.src = videoBlobUrl;
});
}
字符串
在一个运行的环境中,代码运行完美,并提供了正确的高度和宽度的视频所需的结果。我在另一个函数中使用此函数在画布上绘制视频,以在客户端生成视频的缩略图。
但是,当我试图用jest编写一个测试时,与下面的函数相同:
it('should return video metadata', async () => {
// Mock the videoBlobUrl
const videoBlobUrl = 'https://example.com/mock-video-url.mp4';
// Mock the HTMLVideoElement
const videoElementMock: HTMLVideoElement = {
onloadedmetadata: null,
onseeked: null,
onerror: null,
width: 0,
height: 0,
videoWidth: 640, // Mock video width
videoHeight: 480, // Mock video height
duration: 10, // Mock video duration
currentTime: 0,
src: '',
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
play: jest.fn(),
pause: jest.fn(),
load: jest.fn(),
};
// Spy on addEventListener to capture the event handlers
const addEventListenerSpy = jest.spyOn(videoElementMock, 'addEventListener');
// Call the function with the mocked data
const result = await getVideoMetadata(videoBlobUrl, videoElementMock);
// Assertions
expect(videoElementMock.src).toBe(videoBlobUrl);
expect(addEventListenerSpy).toHaveBeenCalledWith('loadedmetadata', expect.any(Function));
expect(addEventListenerSpy).toHaveBeenCalledWith('seeked', expect.any(Function));
// Trigger the loadedmetadata event
const loadedMetadataHandler = (addEventListenerSpy as jest.Mock).mock.calls.find(
(call) => call[0] === 'loadedmetadata',
)[1] as EventListener;
loadedMetadataHandler(new Event('loadedmetadata'));
// Trigger the seeked event
const seekedHandler = (addEventListenerSpy as jest.Mock).mock.calls.find(
(call) => call[0] === 'seeked',
)[1] as EventListener;
seekedHandler(new Event('seeked'));
// Validate the result
expect(result).toEqual({width:640, height:480});
});
型
测试用例总是失败,只要我在测试用例中调用getVideoMetadata
函数,就抛出,而不继续下一行。
thrown: "Exceeded timeout of 5000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
型
我试过增加测试的超时时间,但没有帮助。一旦测试代码videoElement.src = videoBlobUrl;
到达,下一步就会失败,抛出错误。
1条答案
按热度按时间fsi0uk1n1#
我们通过video元素的属性
.onloadedmetadata
、.onseeked
和.onerror
将事件处理程序附加到video元素上。它们都是匿名函数,而不是jestjsmock函数。因此jest.spyOn(videoElementMock, 'addEventListener')
和expect(addEventListenerSpy).toHaveBeenCalledWith('loadedmetadata', expect.any(Function))
将无法工作。由于您传递了
videoElement
togetVideoMetadata
函数,因此在事件发生时修改video元素的属性,您可以在测试中获取video元素的属性(事件处理程序)。然后手动触发它们。例如
getVideoMetadata.test.ts
:字符串
测试结果:
型