Javascript 使用jest模拟jquery单击事件

Javascript 使用jest模拟jquery单击事件,javascript,node.js,jestjs,Javascript,Node.js,Jestjs,我正在尝试为下面的javascript函数编写单元测试 const $ = require("jquery"); const Toggle = (function (toggle, $) { toggle.clickHandler = () => { $(".active").not(this).removeClass("active").next().hide(300); $(this).toggleCla

我正在尝试为下面的javascript函数编写单元测试

const $ = require("jquery");
const Toggle = (function (toggle, $) {
  toggle.clickHandler = () => {
    $(".active").not(this).removeClass("active").next().hide(300);

    $(this).toggleClass("active");

    if (false == $(this).next().is(":visible")) {
      $("#accordion > ul").slideUp(300);
    }
    $(this).next().slideToggle(300);
  };

  $("#accordion > li > div").on("click", toggle.clickHandler);
 
  return {
    toggle,
  };
})({}, $);

module.exports = Toggle.toggle;
我写了下面的笑话测试

const toggle = require("./toggle");
const $ = require("jquery");
jest.dontMock("jquery");
jest.dontMock("./acc");

describe("Toggle", () => {
  it("It should call click handler", () => {
    document.body.innerHTML = ` <ul id="accordion">
    <li>
      <div>Sports</div>
      <ul>
        <li><a href="#">Golf</a></li>
        <li><a href="#">Cricket</a></li>
        <li><a href="#">Football</a></li>
      </ul>
    </li>
    </ul>
    `;
    const spy = jest.spyOn(toggle, "clickHandler");
    $("div").trigger("click");
    $("div").trigger("click");

    expect(spy).toBeCalledTimes(2);
  });
});
const toggle=require(“./toggle”);
const$=require(“jquery”);
jest.dontMock(“jquery”);
开玩笑的唐托克(“附件”);
描述(“切换”,()=>{
它(“它应该调用click处理程序”,()=>{
document.body.innerHTML=`
  • 体育
`; const spy=jest.spyOn(切换“clickHandler”); $(“div”)。触发器(“单击”); $(“div”)。触发器(“单击”); 期望(间谍)。被催缴的时间(2); }); });
但是当我运行测试时,我得到了以下错误


预期调用数:2收到的调用数:0

当您在测试文件开始时从js文件导入时,您将在那时运行所有可调用的代码

这意味着,即使在测试初始化之前,
$(“#accordion>li>div”).on(“click”,toggle.clickHandler)执行,此时DOM中有注释,单击处理程序未注册

正确的方法是公开一个方法来附加click处理程序,并从测试/代码中调用它。比如:

toggle.js

const $ = require("jquery");
const Toggle = (function (toggle, $) {
  toggle.clickHandler = () => {
    $(".active").not(this).removeClass("active").next().hide(300);

    $(this).toggleClass("active");

    if (false == $(this).next().is(":visible")) {
      $("#accordion > ul").slideUp(300);
    }
    $(this).next().slideToggle(300);
    console.log("clicked!");
  };

  toggle.attach = () => { // exposing method to attach handlers
    $("#accordion > li > div").on("click", toggle.clickHandler);
  };

  return {
    toggle
  };
})({}, $);

module.exports = Toggle.toggle;
describe("Toggle", () => {
  it("It should call click handler", async () => {
    document.body.innerHTML = ` <ul id="accordion">
    <li>
      <div>Sports</div>
      <ul>
        <li><a href="#">Golf</a></li>
        <li><a href="#">Cricket</a></li>
        <li><a href="#">Football</a></li>
      </ul>
    </li>
    </ul>
    `;
    const spy = jest.spyOn(toggle, "clickHandler");
    toggle.attach(); // attach handlers
    $("div").trigger("click");
    $("div").trigger("click");

    return new Promise((res, rej) => {
      expect(spy).toBeCalledTimes(2);
      res();
    });
  });
});
toggle.test.js

const $ = require("jquery");
const Toggle = (function (toggle, $) {
  toggle.clickHandler = () => {
    $(".active").not(this).removeClass("active").next().hide(300);

    $(this).toggleClass("active");

    if (false == $(this).next().is(":visible")) {
      $("#accordion > ul").slideUp(300);
    }
    $(this).next().slideToggle(300);
    console.log("clicked!");
  };

  toggle.attach = () => { // exposing method to attach handlers
    $("#accordion > li > div").on("click", toggle.clickHandler);
  };

  return {
    toggle
  };
})({}, $);

module.exports = Toggle.toggle;
describe("Toggle", () => {
  it("It should call click handler", async () => {
    document.body.innerHTML = ` <ul id="accordion">
    <li>
      <div>Sports</div>
      <ul>
        <li><a href="#">Golf</a></li>
        <li><a href="#">Cricket</a></li>
        <li><a href="#">Football</a></li>
      </ul>
    </li>
    </ul>
    `;
    const spy = jest.spyOn(toggle, "clickHandler");
    toggle.attach(); // attach handlers
    $("div").trigger("click");
    $("div").trigger("click");

    return new Promise((res, rej) => {
      expect(spy).toBeCalledTimes(2);
      res();
    });
  });
});
description(“切换”),()=>{
它(“它应该调用click处理程序”,async()=>{
document.body.innerHTML=`
  • 体育
`; const spy=jest.spyOn(切换“clickHandler”); toggle.attach();//附加处理程序 $(“div”)。触发器(“单击”); $(“div”)。触发器(“单击”); 返回新承诺((res,rej)=>{ 期望(间谍)。被催缴的时间(2); res(); }); }); });
这难道没有意义吗?附加事件侦听器后,您正在加载html。@DipenShah:谢谢您的评论。我不明白你能不能解释得更详细一点补充回答。