使用jest模拟jquery click事件

时间:2020-10-17 09:17:04

标签: javascript node.js jestjs

我正在尝试为以下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);
  });
});

但是当我运行测试时,出现以下错误。

预计的通话数量:2已收到的通话数量:0

1 个答案:

答案 0 :(得分:2)

从测试文件开头的js文件导入时,届时所有可调用的代码都已运行。

意思是,即使在初始化测试之前, var userId = User.FindFirst("UserID")?.Value; var data = await _userManager.FindByIdAsync(userId); var user = new UserStandardModel { id = userId, LastName = data.LastName, FirstName = data.FirstName, ProfileImagePath = data.ProfileImagePath }; if (user.ProfileImagePath.StartsWith('C')) { var url = "https://localhost:44356/"; user.ProfileImagePath = user.ProfileImagePath.Remove(0,58); user.ProfileImagePath = url + user.ProfileImagePath; } return Ok(user); 仍会执行,并且由于DOM在当时没有注意,因此未注册点击处理程序。

正确的方法是公开一个方法来附加点击处理程序,并从您的测试/代码中调用它。像这样:

toggle.js

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

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;