You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:AngularJS Keyup指令单元测试——如何检测按键与焦点切换?

嘿,我来帮你搞定这个AngularJS指令的单元测试问题!要检测按键事件和焦点切换,我们可以借助AngularJS的ngMock工具,模拟按键行为并验证焦点状态,下面是具体的步骤和代码示例:

测试箭头键切换焦点指令的完整方案

1. 先搭建测试基础环境

首先要确保你的测试文件引入了AngularJS和ngMock,然后在测试套件里注入$compile和$rootScope,用来编译包含指令的DOM结构:

describe('ArrowKeyFocusDirective', function() {
  var $compile, $rootScope, element, components;

  // 加载你的应用模块
  beforeEach(module('yourAppModule'));

  // 注入测试依赖
  beforeEach(inject(function(_$compile_, _$rootScope_) {
    $compile = _$compile_;
    $rootScope = _$rootScope_;

    // 编译包含指令的DOM(假设指令名为`arrow-key-focus`)
    element = $compile(`
      <div arrow-key-focus>
        <input class="test-component" type="text">
        <input class="test-component" type="text">
        <input class="test-component" type="text">
      </div>
    `)($rootScope);
    $rootScope.$digest(); // 触发AngularJS的脏检查

    // 获取所有需要切换焦点的测试组件
    components = element.find('.test-component');
  }));

2. 测试单个按键事件与焦点切换

接下来我们针对左右箭头键分别写测试用例,核心是模拟按键事件 + 验证焦点元素:

测试右箭头键(→,keyCode 39)

it('should shift focus to the next component when right arrow is pressed', function() {
    // 先让第一个组件获得焦点
    components.eq(0).focus();
    expect(document.activeElement).toBe(components.eq(0)[0]);

    // 模拟右箭头键的keydown事件
    components.eq(0).triggerHandler({
      type: 'keydown',
      keyCode: 39
    });

    // 验证焦点是否切换到第二个组件
    expect(document.activeElement).toBe(components.eq(1)[0]);
  });

测试左箭头键(←,keyCode 37)

it('should shift focus to the previous component when left arrow is pressed', function() {
    // 先让第二个组件获得焦点
    components.eq(1).focus();
    expect(document.activeElement).toBe(components.eq(1)[0]);

    // 模拟左箭头键的keydown事件
    components.eq(1).triggerHandler({
      type: 'keydown',
      keyCode: 37
    });

    // 验证焦点是否切回第一个组件
    expect(document.activeElement).toBe(components.eq(0)[0]);
  });

测试边界情况(防止焦点溢出)

别忘了测试极端场景,比如第一个组件按左箭头、最后一个组件按右箭头时,焦点应该保持不变:

it('should keep focus on first component when left arrow is pressed', function() {
    components.eq(0).focus();
    components.eq(0).triggerHandler({ type: 'keydown', keyCode: 37 });
    expect(document.activeElement).toBe(components.eq(0)[0]);
  });

  it('should keep focus on last component when right arrow is pressed', function() {
    components.eq(2).focus();
    components.eq(2).triggerHandler({ type: 'keydown', keyCode: 39 });
    expect(document.activeElement).toBe(components.eq(2)[0]);
  });
});

几个关键注意点

  • 确保你的指令监听的是keydown事件(keypress事件通常不会捕获箭头键这类功能键)
  • 使用triggerHandler而非trigger来模拟事件,前者不会触发浏览器的默认行为,更适合单元测试场景
  • 验证document.activeElement时,要把jQuery对象转换成原生DOM元素(比如components.eq(0)[0])

内容的提问来源于stack exchange,提问作者user2283403

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:49:29