QUnit测试中调用this.$()提示不是函数的问题求助
解决Ember Mixin测试中
this.$() is not a function的问题 嘿,我来帮你拆解下你遇到的问题,以及怎么修复它:
为什么会报错?
你碰到的this.$() is not a function错误,核心有两个原因:
- 没有正确渲染组件实例:
this.$()是Ember测试助手提供的方法,只有当你通过render()把组件或模板渲染到测试环境的DOM中后,这个方法才会存在于测试上下文里。你现在只是定义了组件类,既没实例化它,也没把它挂载到DOM,自然调用this.$()会报错。 - 断言对象不对:你直接检查
HideOnOutsideClickObject.onOutsideClick,但这是组件类的方法,我们要验证的是组件实例的这个方法是否被触发,而不是类本身有没有这个方法。
修正后的测试代码
import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import HideOnOutsideClick from 'your-app/mixins/hide-on-outside-click'; import Component from '@ember/component'; // 创建测试用的组件,继承目标Mixin const TestComponent = Component.extend(HideOnOutsideClick, { // 可以添加必要的属性,比如默认让组件处于显示状态 isVisible: true }); module('Mixin: HideOnOutsideClick', function(hooks) { setupRenderingTest(hooks); test('triggers onOutsideClick when clicking outside the component', async function(assert) { assert.expect(1); // 把测试组件注册到应用容器里 this.owner.register('component:test-component', TestComponent); // 渲染组件到测试DOM中 await render(hbs`{{test-component}}`); // 获取组件实例,然后mock它的onOutsideClick方法 const component = this.owner.lookup('component:test-component'); component.onOutsideClick = () => { assert.ok(true, 'onOutsideClick was called successfully'); }; // 创建点击事件,并在组件外部(比如body)触发它 const outsideEvent = new MouseEvent('click', { bubbles: true, cancelable: true }); document.body.dispatchEvent(outsideEvent); }); });
关键调整说明
- 用渲染测试助手初始化环境:通过
setupRenderingTest和await render(),我们能正确把组件实例挂载到测试DOM中,这样Mixin的事件监听逻辑才能正常工作。 - Mock实例方法做断言:直接获取组件实例,替换它的
onOutsideClick方法,这样当外部点击触发时,我们就能立刻验证方法是否被调用。 - 正确触发外部点击:选择
document.body作为外部元素触发点击,确保事件能被Mixin的监听逻辑捕获到。
如果你的Ember版本比较新(3.25+),记得用模块化的导入方式,比如import Component from '@ember/component'而不是Ember.Component。
内容的提问来源于stack exchange,提问作者Arnab Datta
相关产品推荐
相关产品推荐

