Next.js + Jest にて export していない関数などのテストをしたい

Jest にてテストを書く時、
基本的には export されたものに対してテストをしていると思う。
でも export されていない関数や型などテストしたい時がある。

下記記事にある3つの方法を試してみる。

上記投稿見る限り、
結局 export を使って外部に出さないとテストできないと思われるので、
出してみる。

環境

  • Next.js v15
  • React v19
  • Node v22
  • Jest v29
  • App Router

構成

/ ─ index.ts
  └ index.test.tsx

その1:テスト用に export する

分かりやすい名前をつけて export する。
ただ、結局普通に export してるだけなので注意。

index.ts

enum TestEnum {
	Success = "success",
}

function testFn() {
	return "success"
}

export const exportedForTesting = {
	TestEnum,
	testFn,
}

index.test.tsx

import { describe, expect, test } from "@jest/globals"
import { exportedForTesting } from "./index"

// ここで定義してもいいかも
const { TestEnum, testFn } = exportedForTesting

describe("その1:テスト用に export する", () => {

	test("enum TestEnum", () => {
		const { TestEnum } = exportedForTesting
		expect(TestEnum.Success).toBe("success")
	})

	test("func testFn()", () => {
		const { testFn } = exportedForTesting
		expect(testFn()).toBe("success")
	})

})

index.ts(use server の場合)

use server を使用する場合、
export する際に、async を使わなければいけないので、
プロパティを export することができないぽい?

"use server"

enum TestEnum {
	Success = "success",
}

function testFn() {
	return "success"
}

export async function exportedForTesting() {
	return {
		TestEnum,
		testFn,
	}
}

index.test.tsx(use server の場合)

import { describe, expect, test } from "@jest/globals"
import { exportedForTesting } from "./index"

describe("その1:テスト用に export する", () => {

	test("enum TestEnum", async () => {
		const { TestEnum } = await exportedForTesting()
		expect(TestEnum.Success).toBe("success")
	})

	test("func testFn()", async () => {
		const { testFn } = await exportedForTesting()
		expect(testFn()).toBe("success")
	})

})

その2: module.exports と process.env.NODE_ENV を使用する

index.ts

Server Component もやることは一緒。
こちらの方が良い感じだけど、
呼び出す側で import と require の2つ使用することになるので、
個人的に少し気持ちが悪い。
あと、 eslint の初期設定ではエラーになる。

enum TestEnum {
	Success = "success",
}

function testFn() {
	return "success"
}

if (process.env.NODE_ENV == "test") {
	module.exports.TestEnum = TestEnum
	module.exports.testFn = testFn
}

index.test.tsx

import { describe, expect, test } from "@jest/globals"
// Error: A `require()` style import is forbidden.  @typescript-eslint/no-require-imports
const exportedForTesting = require("./index")

describe("その2: module.exports と process.env.NODE_ENV を使用する", () => {

	test("enum TestEnum", () => {
		expect(exportedForTesting.TestEnum.Success).toBe("success")
	})

	test("func testFn()", () => {
		expect(exportedForTesting.testFn()).toBe("success")
	})

})

その3: export と process.env.NODE_ENV を使用する

これが今のところ一番しっくりきてる。
が、 Server Components では使えないし、
Next.js のホットリロードで一部記述がエラーになるしで、
けっこう微妙。

index.ts

// Next.js のホットリロード上だとエラーになる
export let exportedForTesting

enum TestEnum {
	Success = "success",
}

function testFn() {
	return "success"
}

if (process.env.NODE_ENV == "test") {
	exportedForTesting = {
		TestEnum,
		testFn
	}
	// ここで export 使うとエラーになる。
	// error: An export declaration can only be used at the top level of a namespace or module.
	// export { testFn }
}

index.test.tsx

import { describe, expect, test } from "@jest/globals"
import { exportedForTesting } from "./index"

describe("その3: export と process.env.NODE_ENV を使用する", () => {

	test("enum TestEnum", () => {
		const { TestEnum } = exportedForTesting
		expect(TestEnum.Success).toBe("success")
	})

	test("func testFn()", () => {
		const { testFn } = exportedForTesting
		expect(testFn()).toBe("success")
	})

})