Handling different implementations for services in different environments, such as testing versus...

A question about default services and contaminating test environments.

I have this service that depends on an import, that needs a bunch of configuration from the development / production environment.

import { authenticate } from "../shopify.server";

export class ShopifyAuthenticate extends Effect.Service<ShopifyAuthenticate>()(
  "shopifyAuthenticate",
  {
    effect: Effect.succeed({
      admin: (req: LoaderFunctionArgs["request"]) =>
        Effect.gen(function* () {
          const { admin } = yield* Effect.tryPromise({
            try: () => authenticate.admin(req),
            catch: (err) => new AuthError(),
          });

          return admin;
        }),
    }),
  },
) {}


I would like to provide an alternative implementation for tests, perhaps the admin object is a bunch of always functions pre-seeded with the values I need for a test.

Unfortunately I can't import this class into my test environment because the default implementation comes along for the ride and doesn't have it's dependencies (environment variables, etc).

Is this where I reach the limit of Effect.Service and should break out separate types, implementations, manually add to the context tag. Or am I holding Effect.service wrong and there's a pattern for dealing with this sort of thing?
Was this page helpful?