effect-testing-mocking について
Effect 開発者向けに、モックサービスと Layer を使った決定的なテスト方法を案内するスキルです。テスト API の実装前に、ローカルの Effect ソースを確認する手順も示します。
主な機能
- 01Layer によるサービスのモック
- 02テスト実装の明示的な提供
- 03決定的なテストクロックの利用
- 04ローカル Effect ソースの優先確認
活用シーン
- 01外部 I/O なしでプログラムをテスト
- 02サービス依存をモックに置き換え
- 03時間依存の動作を決定的に検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mepuka/ effect-ontology --skill effect-testing-mockingインストール後、Claude Code で/effect-testing-mockingを入力して読み込まれたか確認します。
詳細
テストとモック
使用する場面
- 外部 I/O を使わずに、決定的なテストを実行したい場合
- レイヤーを通じてモックサービスを注入したい場合
モックレイヤー
const RepoTest = Layer.succeed(Repo, Repo.of({ find: () => Effect.succeed(mock) }))
テスト実装の提供
const result = yield* Effect.provide(program, RepoTest)
テストクロック
// Provide a deterministic Clock or use platform TestClock layer if available
ガイダンス
- テストの対象を絞って高速に保ち、サービスをモックしてネットワークアクセスを避けます
- プログラムの要件に合わせて、レイヤーを明示的に提供します
- テストを実際のインターフェースに近づけ、テストのためにアプリケーションコードの形を変えないようにします
- 手早く配線するには
.Defaultレイヤーを使い、テストごとにカスタムのモックレイヤーを追加します - すばやく実行でき、すぐに失敗する小規模なスモークテストを優先します
注意点
- テストに実際の I/O が入り込むと、不安定になります
- 内部実装を過剰にモックすると、テストが壊れやすくなります。サービス境界でモックしてください
関連リンク
- DI パターンについては「レイヤーとサービス」を参照してください
- 決定的な時刻と観測可能な出力については「時刻とログ」を参照してください
ローカルソースの参照
重要:実装する前に Effect のローカルソースを検索してください
Effect のソースコード全体は docs/effect-source/ にあります。Effect コードを書く前に、必ず実際の実装を検索してください。
主なソースファイル
- Layer:
docs/effect-source/effect/src/Layer.ts - TestClock:
docs/effect-source/effect/src/TestClock.ts - TestContext:
docs/effect-source/effect/src/TestContext.ts
検索例
# Find Layer.succeed patterns for mocks
grep -F "Layer.succeed" docs/effect-source/effect/src/Layer.ts
# Study TestClock operations
grep -F "TestClock" docs/effect-source/effect/src/TestClock.ts
# Find test helpers
grep -F "TestContext" docs/effect-source/effect/src/TestContext.ts
# Look at Layer test examples
grep -F "Layer.succeed" docs/effect-source/effect/test/Layer.test.ts
ワークフロー
- 必要なテスト API を特定します(例:Layer.succeed、TestClock)
docs/effect-source/effect/src/Layer.tsで実装を検索します- 型とテストのパターンを調べます
- 使用例について、テストファイルを確認します
- 実際の実装に基づいてコードを書きます
実際のソースコード > ドキュメント > 推測
実例:包括的なテストレイヤーを構築する
export const TestLayer = (input?: TestLiveInput) =>
Effect.gen(function* () {
const tempDir = tempy.temporaryDirectory({ prefix: 'test' })
const cwd = (yield* setupFixtureFolder({ fixture: input?.fixture, tempDir })) ?? tempDir
const NodeOsTest = Layer.succeed(NodeOs, new NodeOs({ homedir: cwd, arch: 'arm64', platform: 'darwin' }))
const NodeProcessTest = Layer.succeed(NodeProcess, new NodeProcess({ cwd, platform: 'darwin', arch: 'arm64' }))
const ToolkitsRepoTest = Layer.succeed(ComposioToolkitsRepository, new ComposioToolkitsRepository({
getToolkits: () => Effect.succeed([]),
getToolsAsEnums: () => Effect.succeed([])
}))
const layers = Layer.mergeAll(
Console.setConsole(yield* MockConsole.effect),
CliConfig.layer(ComposioCliConfig),
NodeProcessTest,
Layer.provideMerge(ComposioUserContextLive, Layer.merge(BunFileSystem.layer, NodeOsTest)),
ToolkitsRepoTest,
EnvLangDetector.Default,
JsPackageManagerDetector.Default,
BunFileSystem.layer,
BunContext.layer,
MockTerminal.layer,
BunPath.layer
)
return layers
}).pipe(
Logger.withMinimumLogLevel(LogLevel.Debug),
Effect.scoped,
Layer.unwrapEffect,
Layer.provide(Layer.setConfigProvider(input?.baseConfigProvider ?? ConfigProvider.fromMap(new Map([]))))
)
参考資料
- Agent Skills の概要:https://www.anthropic.com/news/skills
- Skills ガイド:https://docs.claude.com/en/docs/claude-code/skills
コメント
Markdown 対応