Skip to content
← Back to rules

jest/require-hook スタイル

何をするか

このルールは、テストファイルのトップレベルにあるか、describe の本体に直接含まれるすべての式に対して警告を出します。ただし以下のものは例外です:

  • import ステートメント
  • const 変数
  • let 宣言 および nullundefined への初期化
  • クラス
  • タイプ
  • 標準の Jest グローバル関数の呼び出し

なぜ問題なのか

フック外にセットアップやティーダウンコードを記述すると、予測できないテスト動作が発生する可能性があります。トップレベルで実行されるコードは、テストファイルが読み込まれた時点で実行されますが、テストが実行されたときには実行されません。これによりテストの分離性が損なわれ、テストの実行順序に依存した脆弱なコードが生まれます。beforeEachbeforeAllafterEachafterAll などの適切なフックを使用することで、セットアップやティーダウンコードが正しいタイミングで実行され、テストの分離性が維持されます。

このルールに対する誤りなコード例:

javascript
import { database, isCity } from "../database";
import { Logger } from "../../../src/Logger";
import { loadCities } from "../api";

jest.mock("../api");

const initializeCityDatabase = () => {
  database.addCity("Vienna");
  database.addCity("San Juan");
  database.addCity("Wellington");
};

const clearCityDatabase = () => {
  database.clear();
};

initializeCityDatabase();

test("that persists cities", () => {
  expect(database.cities.length).toHaveLength(3);
});
test("city database has Vienna", () => {
  expect(isCity("Vienna")).toBeTruthy();
});

test("city database has San Juan", () => {
  expect(isCity("San Juan")).toBeTruthy();
});

describe("when loading cities from the api", () => {
  let consoleWarnSpy = jest.spyOn(console, "warn");
  loadCities.mockResolvedValue(["Wellington", "London"]);

  it("does not duplicate cities", async () => {
    await database.loadCities();
    expect(database.cities).toHaveLength(4);
  });
});
clearCityDatabase();

このルールに対する正しいコード例:

javascript
import { database, isCity } from "../database";
import { Logger } from "../../../src/Logger";
import { loadCities } from "../api";

jest.mock("../api");
const initializeCityDatabase = () => {
  database.addCity("Vienna");
  database.addCity("San Juan");
  database.addCity("Wellington");
};

const clearCityDatabase = () => {
  database.clear();
};

beforeEach(() => {
  initializeCityDatabase();
});

test("that persists cities", () => {
  expect(database.cities.length).toHaveLength(3);
});

test("city database has Vienna", () => {
  expect(isCity("Vienna")).toBeTruthy();
});

test("city database has San Juan", () => {
  expect(isCity("San Juan")).toBeTruthy();
});

describe("when loading cities from the api", () => {
  let consoleWarnSpy;
  beforeEach(() => {
    consoleWarnSpy = jest.spyOn(console, "warn");
    loadCities.mockResolvedValue(["Wellington", "London"]);
  });

  it("does not duplicate cities", async () => {
    await database.loadCities();
    expect(database.cities).toHaveLength(4);
  });
});
afterEach(() => {
  clearCityDatabase();
});

このルールは eslint-plugin-vitest と互換性があります。使用するには、.oxlintrc.json に以下の設定を追加してください:

json
{
  "rules": {
    "vitest/require-hook": "error"
  }
}

設定

このルールは以下のプロパティを持つ設定オブジェクトを受け入れます:

allowedFunctionCalls

type: string[]

default: []

フック外で呼び出しても許可される関数名の配列。

使用方法

このルールを有効にするには、設定ファイルまたは CLI で次のように使用できます:

json
{
  "plugins": ["jest"],
  "rules": {
    "jest/require-hook": "error"
  }
}
bash
oxlint --deny jest/require-hook --jest-plugin

参照