Guides

Testing Policies

Learn how to unit-test your OPA policies with the built-in Rego test runner, write integration tests against a local Engine, and mock Lelu in application tests.

1. Unit Testing with OPA

OPA ships a built-in test runner. Place test files alongside your policy with a _test suffix.

policy/auth_test.rego
package lelu.authz_test

import data.lelu.authz

# High confidence → auto-allow
test_high_confidence_allow {
  authz.allow with input as {
    "confidence": 0.95,
    "action": "send_email"
  }
}

# Low confidence → deny
test_low_confidence_deny {
  not authz.allow with input as {
    "confidence": 0.3,
    "action": "send_email"
  }
}

# Medium confidence → require review
test_medium_review {
  authz.require_review with input as {
    "confidence": 0.7,
    "action": "send_email"
  }
}
terminal
opa test ./policy/ -v

2. Integration Tests with a Local Engine

Spin up a local Engine with docker compose and run against it in tests.

tests/integration.test.ts
import { LeluClient } from "@lelu-auth/lelu";

const lelu = new LeluClient({
  baseUrl: "http://localhost:8082",
  apiKey: "test-key",
});

describe("Lelu Engine", () => {
  it("allows high-confidence actions", async () => {
    const decision = await lelu.authorize({
      action: "send_email",
      confidence: 0.95,
    });
    expect(decision.status).toBe("allow");
  });

  it("routes low-confidence to queue", async () => {
    const decision = await lelu.authorize({
      action: "delete_records",
      confidence: 0.3,
    });
    expect(decision.status).toBe("deny");
  });
});

3. Mocking Lelu in Application Tests

For unit tests that don't need the Engine running, mock the SDK client.

setupTests.ts
import { vi } from "vitest";

vi.mock("lelu", () => ({
  LeluClient: vi.fn().mockImplementation(() => ({
    authorize: vi.fn().mockResolvedValue({
      status: "allow",
      requestId: "mock-id",
      requiresHumanReview: false,
      allowed: true,
    }),
  })),
}));