簡體   English   中英

ES6 class 的自動模擬失敗(Jest,Vanilla JavaScript)

[英]Automatic mock of an ES6 class fails (Jest, Vanilla JavaScript)

我有 class FooStorage ,它有一個Foo對象數組作為成員變量。 測試FooStorage時,我想模擬 class Foo
ES6 Class Mocks所述,在我的案例中,我只需要一個自動模擬。 但是當我嘗試模擬 class 時,它似乎並沒有成功。 相反,當我嘗試使用mockClear()重置模擬時,我收到一條錯誤消息。

以下是來自 jest 的代碼和 output:


foo.js

class Foo {};

export default Foo;

foostorage.js

import Foo from "./foo.js";

class FooStorage {
    constructor() {
        this.storage = []; // Array of Foo objects
    }
}

export default FooStorage;

foostorage.test.js

import Foo from "../src/foo.js";
import FooStorage from "../src/foostorage.js";

import { jest } from "@jest/globals";

jest.mock("../src/foo.js");

beforeEach(() => {
    Foo.mockClear();
});

test("if the Foo constructor hasn`t been called", () => {
    const storage = new FooStorage();
    expect(Foo).not.toHaveBeenCalled();
});

output

if the Foo constructor hasn`t been called

TypeError: Foo.mockClear is not a function

   7 |
   8 | beforeEach(() => {
>  9 |      Foo.mockClear();
     |          ^
  10 | });
  11 |
  12 | test("if the Foo constructor hasn`t been called", () => {

  at Object.<anonymous> (test/foostorage.test.js:9:6)

我已經試過把jest.mock("../src/foo.js"); import Foo from "../src/foo.js"; 但問題沒有解決。


編輯:

我將 Jest v. 27.0.6jest-environment-node v. 27.0.6@types/jest v. 27.0.1
我還使用 nodejs arguments --experimental-modules--experimental-vm-modules以便我可以使用 ES6 導入。 我不使用 Babel 或其他任何東西。 只是簡單的 JavaScript。

自動 mocking 應該像文檔解釋的那樣工作。 如果沒有並導致上述錯誤,則意味着該模塊未被模擬,因此手動模擬也會失敗。 這可能是因為 mock 沒有正確執行(模塊路徑中的大小寫或擴展不同),或者jest.mock提升不起作用(最常見的原因是錯誤配置的 Babel 轉換)。

這段代碼與文檔中顯示的不同之處在於, jest global 是常用的,而這里是導入值,因此與使用jest global 不同。 這是提升以不同方式工作的明顯且已知的原因

可以通過以不干擾預期執行順序的方式對依賴項進行排序來修復:

import { jest } from "@jest/globals";

jest.mock("../src/foo.js");

import Foo from "../src/foo.js";
...

jest.mock的提升依賴於未記錄的、不符合規范的 hack,這也取決於 Jest 版本和特定設置。 它不能保證工作,因為 ES 導入預計會根據規范提升到其他聲明之上,並且沒有排除項。

一個過時但穩定的解決方法是切換到require常規 JavaScript function 調用並按原樣評估:

let { jest } = require ("@jest/globals");

jest.mock("../src/foo.js");

let { default: Foo } = require("../src/foo.js");
...

一個有效的解決方案是擺脫jest導入並設置一個具有各自全局變量的通用 Jest 環境,因此無論 Jest 版本和其他情況如何, jest.mock都可以按預期方式提升。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM