无法在测试中模拟事件处理程序
Unable to mock event handler on test
所以我有一个非常简单的 class,它执行以下操作:
- 在创建的元素上添加事件处理程序
- 事件处理程序是 class
的实例方法
- 我需要一个
cleanup
方法来按需删除处理程序
export default class TestClass {
constructor() {
this.element = document.getElementById("test");
this.element.addEventListener("click", this.clickHandler);
}
clickHandler(e) {
console.log("Click handler called");
}
cleanup() {
this.element.removeEventListener("click", this.clickHandler);
}
}
我有一个测试,其中我 stub 处理程序(我需要更改它的行为)并进行一些检查。
describe("Test", function () {
beforeEach(function () {
this.instance = new TestClass();
this.clickHandlerStub = sinon.stub(this.instance, "clickHandler");
});
afterEach(function () {
this.instance.cleanup();
delete this.instance;
});
it("test case", function () {
document.getElementById("test").click();
expect(this.clickHandlerStub.calledOnce).to.equal(true);
});
});
预期的行为是 stub
(覆盖)处理程序(因此不应出现日志记录)并且我的期望应该通过,因为它应该在单击元素时调用一次。
但是它似乎一直在记录并且期望失败。
如果我改变绑定事件处理程序的方式并使用箭头函数,一切正常。
this.element.addEventListener("click", () => this.clickHandler());
但是我无法删除 cleanup
方法中的事件处理程序,因为 addEventListener
和 removeEventListener
需要传递相同的处理程序引用才能正常工作。
我创建了一个 reproducable example in codesandbox 以防有帮助。
那么我在这里错过了什么?
您可以stub
TestClass
的原型。
this.clickHandlerStub = sinon
.stub(TestClass.prototype, "clickHandler")
.callsFake(() => {
console.log(`Now it's calling the fake handler`);
});
清理将是
this.clickHandlerStub.restore();
https://codesandbox.io/s/mocha-unit-test-example-forked-sstfz?file=/src/index.js
参考文献:
- Restore sinon stub
顺便说一下,我不喜欢在全局上下文中使用 this
。相反,我将它们创建为 let
变量。
describe('...', () => {
let clickHandlerStub;
beforeEach(() => {
clickHandlerStub = ...
});
afterEach(() => {
clickHandlerStub.restore();
});
});
所以我有一个非常简单的 class,它执行以下操作:
- 在创建的元素上添加事件处理程序
- 事件处理程序是 class 的实例方法
- 我需要一个
cleanup
方法来按需删除处理程序
export default class TestClass {
constructor() {
this.element = document.getElementById("test");
this.element.addEventListener("click", this.clickHandler);
}
clickHandler(e) {
console.log("Click handler called");
}
cleanup() {
this.element.removeEventListener("click", this.clickHandler);
}
}
我有一个测试,其中我 stub 处理程序(我需要更改它的行为)并进行一些检查。
describe("Test", function () {
beforeEach(function () {
this.instance = new TestClass();
this.clickHandlerStub = sinon.stub(this.instance, "clickHandler");
});
afterEach(function () {
this.instance.cleanup();
delete this.instance;
});
it("test case", function () {
document.getElementById("test").click();
expect(this.clickHandlerStub.calledOnce).to.equal(true);
});
});
预期的行为是 stub
(覆盖)处理程序(因此不应出现日志记录)并且我的期望应该通过,因为它应该在单击元素时调用一次。
但是它似乎一直在记录并且期望失败。
如果我改变绑定事件处理程序的方式并使用箭头函数,一切正常。
this.element.addEventListener("click", () => this.clickHandler());
但是我无法删除 cleanup
方法中的事件处理程序,因为 addEventListener
和 removeEventListener
需要传递相同的处理程序引用才能正常工作。
我创建了一个 reproducable example in codesandbox 以防有帮助。
那么我在这里错过了什么?
您可以stub
TestClass
的原型。
this.clickHandlerStub = sinon
.stub(TestClass.prototype, "clickHandler")
.callsFake(() => {
console.log(`Now it's calling the fake handler`);
});
清理将是
this.clickHandlerStub.restore();
https://codesandbox.io/s/mocha-unit-test-example-forked-sstfz?file=/src/index.js
参考文献:
- Restore sinon stub
顺便说一下,我不喜欢在全局上下文中使用 this
。相反,我将它们创建为 let
变量。
describe('...', () => {
let clickHandlerStub;
beforeEach(() => {
clickHandlerStub = ...
});
afterEach(() => {
clickHandlerStub.restore();
});
});