【问题标题】:Jest - Pass mocked instance as class constructor argument开玩笑 - 将模拟实例作为类构造函数参数传递
【发布时间】:2021-03-09 09:50:11
【问题描述】:

我目前正在尝试用 jest(新手)编写一些测试。关于我最新的post,我遇到了以下情况:

我有多个价格字段。每个价格字段都有自己的渲染器。渲染器具有对其价格字段的引用。 pricefield 可以从 dom 中确定一些 html sn-p。

// priceField.js

class PriceField {
  constructor() {
    const renderer = new PriceFieldRenderer(this);
    // do something with renderer
  }

  /**
   * Determines Node in DOM for this price field
   */
  determinePriceFieldNode() {
    return document.querySelector(".price-field");
  }
}

export default PriceField;

// priceFieldRenderer.js

class PriceFieldRenderer {
  constructor(priceField) {
    this.priceFieldNode = priceField.determinePriceFieldNode();
  }
}

export default PriceFieldRenderer;

现在我想测试PriceFieldRenderer(开玩笑)。因此,我需要模拟PriceField 及其determinePriceFieldNode() 函数。

但是,我无法将模拟的价格字段实例作为构造函数参数传递。我已经阅读了带有声音播放器示例的官方文档,并在谷歌上搜索了大约 2 小时。我也测试了不同的实现,但我无法解决它。这是一个引发以下错误的代码 sn-p:TypeError: priceField.determinePriceFieldNode is not a function


jest.mock("./priceField");

import PriceFieldRenderer from "./priceFieldRenderer";
import PriceField from "./priceField";

describe("Price field renderer", () => {
  test("with calculated price", () => {
    const priceField = PriceField.mockImplementation(() => {
      return {
        determinePriceFieldNode: () => "<html/>"
      };
    });

    const sut = new PriceFieldRenderer(priceField);

    expect(sut).toBeDefined();
  });
});

我确信我做的方式不是最好的,那里有一些帮助:)

【问题讨论】:

    标签: javascript jestjs


    【解决方案1】:

    这里的问题是priceField 是小写的,并假设它是一个实例,而它是应该创建实例的间谍函数。它可以通过以下方式修复:

    PriceField.mockImplementation(...);
    const priceField = new PriceField();
    const sut = new PriceFieldRenderer(priceField);
    

    priceField 模块模拟和关联的PriceField spy 没有任何用处。如果将其导入并在另一个模块中使用,则需要它们,这是来自 Jest 文档显示的 the said example

    PriceFieldRenderer 使用依赖注入使测试更简单,这是该模式的好处之一:

    const priceField = { determinePriceFieldNode: jest.fn(() => "<html/>") });
    const sut = new PriceFieldRenderer(priceField);
    

    【讨论】:

    • 感谢您的快速回答。我遇到了一个关于关注post 的类似解决方案:PriceField.prototype.determinePriceFieldNode = jest.fn().mockImplementation(...) 但是,您对 depencey 注入的提示非常好!
    • 不客气。 FWIW,PriceField.prototype.determinePriceFieldNode = jest.fn() 是一种反模式,它防止方法被恢复,作为经验法则,jest.spyOn 应该用于现有对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 2020-07-09
    • 2023-02-15
    • 2022-12-01
    • 1970-01-01
    相关资源
    最近更新 更多