Replacing Default Dependencies with Mocks for Testing in TypeScript

I have a question about replacing dependencies with mocks for testing. For context, my aim is to replace a function that builds the default (live) dependency with a different one for testing. I seem to be unable to achieve it. What is the proper way to replace default provided dependencies with ones for testing?

interface Foo { bar(): number }
const Foo = Context.GenericTag<Foo>('Foo')
const FooBuilder = Context.GenericTag<() => Foo>('FooBuilder')
const FooTestDouble = { value: 42, bar: () => FooTest.value }

const Main = Effect.gen(function*(){
    const foo = yield* Foo
    // ...
    return foo.bar()
})

Defaults satisfies (..._:never) => Effect.Effect<unknown,unknown,never>
function Defaults(e: typeof Main) {
    return pipe(
        e,
        // This example has very few dependencies, but we could have loads of dependencies here in production code
        Effect.provideServiceEffect(Foo, Effect.map(FooBuilder, e => e())),
        Effect.provideService(FooBuilder, () => { throw 'oh no! :('}),
    )
}

it("Replaces FooBuilder", async () => {
    const result = await pipe(
        Main,
        // TODO: How to replace FooBuilder with () => FooTestDouble ?
        Defaults,
        Effect.runPromise,
    )
    expect(result).toBe(FooTestDouble.value)
})
Was this page helpful?