🧪
Testのためだけに関数をexportしたくない【TypeScript🔥】
テストのためにexportしている辛さ
他のファイルから参照されないように private関数として定義したい関数なのに、テストのためだけにexportしないといけないのは辛い。
hoge.ts
// 責務を分離するために関数に切り出したが、hoge.ts内部に閉じたprivate関数でいたい。
// なのにテスト用にexportしないといけない、、
export const privateMethodForHoge = (arg: string): string => {
// 省略
}
// これは外側のファイルから呼び出されるつもりの関数
export const doHogeForPublicUse = (arg: string): string => {
// 中略
return privateMethodForHoge(arg)
}
案1: In-Source Testingを使う
ソースコードと一緒にテストがかける。
hoge.ts
const privateMethodForHoge = (arg: string): string => {
// 省略
}
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest
it('privateMethodForHoge', () => {
const input = "fuga"
const expected = "hoge"
const actual = privateMethodForHoge(input)
expect(actual).toBe(expected)
})
}
メリット
- 本来したくなかったexportが不要になる。
- コードが見づらいと思いきや、テストコードは仕様書を兼ねるという考え方を持つとテストとコードがセットで書かれているのは逆に閲覧性が高いのかもしれない。
デメリット
- コードが見づらい。
案2 テスト用として明示してexportする
__test__みたいなめっちゃテストっぽいobjectでexportしておくという方法
hoge.ts
const privateMethodForHoge = (arg: string): string => {
// 省略
}
// テスト用のobjectとしてexportする。
export const __test__ = {
privateMethodForHoge,
// 他にもこのファイル内でテストしたいprivate関数はここに追加する
};
hoge.test.ts
import { describe, expect, it } from "vitest";
import { __test__ } from "./hoge";
const { privateMethodForHoge } = __test__;
describe("privateMethodForHoge", () => {
it('fugaはhogeになる', () => {
const input = "fuga"
const expected = "hoge"
const actual = privateMethodForHoge(input)
expect(actual).toBe(expected)
})
})
メリット
- vitestの仕様がソースコード側に漏れ出ないので綺麗な気がする
- exportしていることには代わりないが、
__test__というあからさまな名前にしておくことで Codex君やClaudeCode君に気づいてもらえる。
デメリット
- なれない書き方でコツがいる? → AGENTS.mdに書いてAIに徹底させれば良し
おわりに
案2を使っていこうと思います。
Discussion