【问题标题】:Custom event parameter is not passed correctly in test自定义事件参数在测试中未正确传递
【发布时间】:2020-01-05 23:00:19
【问题描述】:

我开发了一个 JavaScript 库来处理由游戏手柄/操纵杆生成的事件,并且我还使用 Jest 针对不同的测试用例开发了一系列测试。但是我的测试有一个问题:我不知道如何模拟gamepadconnectedgamepaddisconnected 事件。

这是我的代码的简化版本:

const gameControl = {
  // ...
  init: function() {
    window.addEventListener('gamepadconnected', e => {
      console.log('gamepad detected');
      if (!window.gamepads) window.gamepads = {};
      if (e.gamepad) {
        if (!window.gamepads[e.gamepad.index]) {
          window.gamepads[e.gamepad.index] = e.gamepad;
          // ...
        }
      }
    });
    window.addEventListener('gamepaddisconnected', e => {
      console.log('gamepad disconnected');
      if (e.gamepad) {
        delete window.gamepads[e.gamepad.index];
        // ...
      }
    });
  }
  // ...
};

gameControl.init();

export default gameControl;

gamepadconnectedgamepaddisconnected 是分别在连接或断开游戏手柄/操纵杆时触发的原生事件。作为参数,它们接收具有gamepad 属性的事件对象,该对象包含有关已连接/已断开连接的游戏手柄的信息。

我尝试在测试中手动调度事件,creating my own custom event with the parameter I want(下面的gamepads 是一个包含游戏手柄模拟数据的数组)。像这样的:

describe('gameControl', () => {

  // ...

  test('trigger gamepadconnected event', () => {
    const event = new CustomEvent('gamepadconnected', {
      detail: { gamepad: gamepads[0] }
    });
    global.dispatchEvent(event);
  });

  test('trigger gamepaddisconnected event', () => {
    const event = new CustomEvent('gamepaddisconnected', {
      detail: { gamepad: gamepads[0] }
    });
    global.dispatchEvent(event);
  });

  // ...

});

但是,尽管事件被正确分派并触发了事件监听器,但参数并没有通过。例如,gamepadconnected 已处理,我在控制台中看到“检测到游戏手柄”,但对象 e 不包含我需要的属性 gamepad

我做了一个console.log(e) 来查看事件对象的属性,但是我的参数无处可见。这就是console.log 的所有节目:

CustomEvent { isTrusted: [Getter] }

我做错了什么?如何实现我想要的并测试 gamepadconnectedgamepaddisconnected 的事件处理程序的完整代码?

作为替代方案,我尝试将gamepad 属性移至顶层,或使用Event 而不是CustomEvent,但问题仍然存在。

test('trigger gamepaddisconnected event', () => {
  const event = new CustomEvent('gamepaddisconnected', {
    gamepad: gamepads[0]
  });
  global.dispatchEvent(event);
});

test('trigger gamepaddisconnected event', () => {
  const event = new Event('gamepaddisconnected', {
    gamepad: gamepads[0]
  });
  global.dispatchEvent(event);
});

【问题讨论】:

  • 我也遇到了这种情况。我正在使用开玩笑的测试库。当我从测试文件中的带有事件侦听器的 src 文件调度 CustomEvent 时,我可以看到事件详细信息对象。当我从我的 src 文件中的带有事件侦听器的测试文件中调度 CustomEvent 时,详细对象不存在,并且我在 console.logging 时看到的只是:CustomEvent { isTrusted: [Getter] }

标签: javascript unit-testing testing jestjs


【解决方案1】:

想到一个懒惰的技巧:只需检查是否定义了 e.detail.gamepad,然后将 e.gamepad 设置为 e.detail.gamepad

window.addEventListener('gamepadconnected', e => {
   if(e.detail && e.detail.gamepad) { e.gamepad = e.detail.gamepad }
...

【讨论】:

  • 这与我最终所做的想法相似 (const egp = e.gamepad || e.detail.gamepad)。它有效,但正如你提到的,它是一个黑客。我正在更改库/应用程序代码以使其适应测试代码,这并不理想。
  • 真的...但最终你还是获得了对“模拟游戏手柄”的支持 ;-)
  • 是的,这很糟糕......改变生产代码以适应测试!
猜你喜欢
  • 2010-10-24
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-24
  • 2012-07-30
  • 1970-01-01
相关资源
最近更新 更多