Effect.ts: Absence as First-Class

Advanced PatternsLesson 45 of 51

45. Testing - Providing Test Dependencies

Tests provide FAKE services - absence resolved with test doubles!

Code Example
// Production code requires real Database
const getUser = (id: string) =>
  Effect.gen(function* () {
    const db = yield* Database;  // Absent!
    return yield* db.query(`SELECT...`);
  });

// Test: provide FAKE database
const TestDatabase = Layer.succeed(Database, {
  query: (sql) => Effect.succeed({ id: "123", name: "Test User" })
});

// Run test with fake dependency
const test = Effect.gen(function* () {
  const user = yield* getUser("123");
  // user = Test User (from fake DB!)
}).pipe(
  Effect.provide(TestDatabase)
);

// Same absent requirement, different resolution!
Interactive Example
const output: string[] = [];
output.push('Testing with Effect:');
output.push('');
output.push('Production:');
output.push('  getUser(id).pipe(');
output.push('    Effect.provide(DatabaseLive)');
output.push('  )');
output.push('');
output.push('Test:');
output.push('  getUser(id).pipe(');
output.push('    Effect.provide(DatabaseTest)');
output.push('  )');
output.push('');
output.push('Same code, different dependencies!');
output.push('');
output.push(' Testable by design!');
return output.join('
');
Explanation

Testing: resolving absence with test doubles.

Traditional approach: global mocks, brittle tests. Effect types test dependencies as alternate absence resolution:

  • Production: Database is absent → provide real DB
  • Test: Database is absent → provide fake DB
  • Same code, different resolution strategy
  • No assumptions about which Database
  • Type system ensures we provide something

Absence-first testing: dependencies are just absence to resolve!


Part 45 of 51 in the Effect.ts Absence Modeling series