模拟茉莉花中的假按键

时间:2014-11-17 05:21:44

标签: javascript unit-testing jasmine

我试图模拟Jasmine中的按键(测试浏览器是PhantomJS),因此我可以对使用按键操作的一些功能进行单元测试。不幸的是,我无法使用Jasmine对其进行正确测试,因为我收到了错误。

这是我试图测试的代码:

function Controls() {
  'use strict';
  this.codes = {
    37: 'left',
    39: 'right',
    38: 'forward',
    40: 'backward'
  };
  this.states = {
    'left': false,
    'right': false,
    'forward': false,
    'backward': false
  };
  document.addEventListener('keydown', function() { this.onKey.bind(this, true); }, false);
  document.addEventListener('keyup', function() { this.onKey.bind(this, false); }, false);
}

Controls.prototype.onKey = function(val, e) {
  var state = this.codes[e.keyCode];

  if (typeof state === 'undefined') return false;

  this.states[state] = val;

  // Stop the key press from repeating
  e.preventDefault();
  e.stopPropagation();

  return true;
};

controls = new Controls();

(注意:上面的代码使用anon函数包装addEventListener中的函数,以便Jasmine实际上将尝试运行我的测试。如果没有匿名换行,这会导致另一个错误:TypeError: 'undefined' is not a function (evaulating 'this.onKey.bind(this, true)'解决此问题将是太好了。 )

这是我尝试测试的:

function keyPress(key) {
  var pressEvent = document.createEvent('KeyboardEvent');
  pressEvent.initKeyEvent('keydown', true, true, window,
                            false, false, false, false,
                            0, key);
  document.dispatchEvent(pressEvent);
}

describe("Controls", function() {
  var controls;

  it("should initialize properly", function() {
    controls = new Controls();
    expect(controls).not.toBe(null);
  });

  it("should reflect changes in state when arrow keys are used", function() {
    keyPress(37);
    expect(controls.states[state]).toBe(37);
  });
});

这会导致Jasmine出错:

TypeError: 'undefined' is not a function (evaluating 'pressEvent.initKeyEvent('keydown', true, true, window, false, false, false, false, 0, key)')

我对Jasmine(以及Javascript)仍然很新,所以任何帮助一般都会受到赞赏。

2 个答案:

答案 0 :(得分:16)

看起来您的问题在于如何创建活动。

下面的示例代码显示了如何创建,触发和拦截事件。

var keyPressed = null;

function keyPress(key) {
  var event = document.createEvent('Event');
  event.keyCode = key; // Deprecated, prefer .key instead.
  event.key = key;
  event.initEvent('keydown');
  document.dispatchEvent(event);
}

document.addEventListener('keydown', function(e){
   keyPressed = e.key;
});

keyPress(37)
alert(keyPressed);

这里也是一名傻瓜:http://plnkr.co/edit/TxGXcT0DnPa44C0PkHkN?p=preview

如评论所述,有关.keyCode弃用的信息,请参阅here

答案 1 :(得分:3)

编辑:此问题应从PhantomJS 2开始解决。以下问题中的更多信息。

所以原因

this.onKey.bind(this, true)

返回错误是因为截至本文发布之日,PhantomJS尚未支持绑定。您可以在此处找到更多相关信息:

https://github.com/ariya/phantomjs/issues/10522

以及来自ariya的更长解释:

https://groups.google.com/forum/#!msg/phantomjs/r0hPOmnCUpc/uxusqsl2LNoJ

解决此问题的方法是按照creationix:

的建议创建一个polyfill

https://github.com/c9/smith/blob/master/tests/public/test.js#L2-L7

鉴于所有这些信息,它应该使测试更易于管理,因为我知道我可以绕过原型问题。感谢您的帮助!

相关问题