56 results available
Sign in
Skills directory

testing

encoredev

·

Last changed
Hardened

This skill has been hardened by Chainguard

Last changed

This version passed the hardening gate. Hardening applied 6 targeted changes and preserved all other text. Classified findings before hardening: 1. Classified findings closed: 0. Classified findings remaining: 1. Unclassified scanner findings remaining: 0. Review findings closed: 4. Review findings remaining: 8.


Open before hardening

1

Low
Open after hardening

1

Low

Expand
File
Group
Subtype
Severity
Status
SKILL.md

Prompt Injection

Third-party content as instructions

Low
Open

1 finding


SKILL.md

Testing Encore.ts Applications

Instructions

Encore.ts uses standard TypeScript testing tools. The recommended setup is Vitest.

Setup Vitest

npm install -D vitest

Add to package.json:

{
  "scripts": {
    "test": "vitest"
  }
}

Test an API Endpoint

// api.test.ts
import { describe, it, expect } from "vitest";
import { hello } from "./api";

describe("hello endpoint", () => {
  it("returns a greeting", async () => {
    const response = await hello();
    expect(response.message).toBe("Hello, World!");
  });
});

Run Tests

# Run with Encore (recommended - sets up infrastructure)
encore test

Using encore test is recommended because it:

  • Sets up test databases automatically
  • Handles service dependencies

Test with Request Parameters

// api.test.ts
import { describe, it, expect } from "vitest";
import { getUser } from "./api";

describe("getUser endpoint", () => {
  it("returns the user by ID", async () => {
    const user = await getUser({ id: "123" });
    expect(user.id).toBe("123");
    expect(user.name).toBeDefined();
  });
});

Test Database Operations

Encore provides isolated test databases:

// user.test.ts
import { describe, it, expect, beforeEach } from "vitest";
import { createUser, getUser, db } from "./user";

describe("user operations", () => {
  beforeEach(async () => {
    // Clean up before each test
    await db.exec`DELETE FROM users`;
  });

  it("creates and retrieves a user", async () => {
    const created = await createUser({ email: "test@example.com", name: "Test" });
    const retrieved = await getUser({ id: created.id });
    
    expect(retrieved.email).toBe("test@example.com");
  });
});

Test Service-to-Service Calls

// order.test.ts
import { describe, it, expect } from "vitest";
import { createOrder } from "./order";

describe("order service", () => {
  it("creates an order and notifies user service", async () => {
    // Service calls work normally in tests
    const order = await createOrder({
      userId: "user-123",
      items: [{ productId: "prod-1", quantity: 2 }],
    });
    
    expect(order.id).toBeDefined();
    expect(order.status).toBe("pending");
  });
});

Test Error Cases

import { describe, it, expect } from "vitest";
import { getUser } from "./api";

describe("error handling", () => {
  it("throws NotFound for missing user", async () => {
    await expect(getUser({ id: "nonexistent" }))
      .rejects
      .toThrow("user not found");
  });
});

Test Authenticated Endpoints

Mock getAuthData to call auth: true endpoints directly as a given user:

import { describe, it, expect, vi } from "vitest";
import * as auth from "~encore/auth";
import { getProfile } from "./api";

it("returns the caller's profile", async () => {
  vi.spyOn(auth, "getAuthData").mockImplementation(() => ({ userID: "123" }));
  const profile = await getProfile();
  expect(profile.id).toBe("123");
});

The mock only affects code in the test process that reads getAuthData() directly. Calls made through ~encore/clients go through the Encore runtime, which does not see the mock, so an auth: true endpoint called that way fails with "endpoint requires auth but none provided". Pass the auth data explicitly instead:

import { user } from "~encore/clients";

await user.follow({ username: "jake" }, { authData: { userID: "123" } });

Test Pub/Sub

// notifications.test.ts
import { describe, it, expect, vi } from "vitest";
import { orderCreated } from "./events";

describe("pub/sub", () => {
  it("publishes order created event", async () => {
    const messageId = await orderCreated.publish({
      orderId: "order-123",
      userId: "user-456",
      total: 9999,
    });
    
    expect(messageId).toBeDefined();
  });
});

Test Cron Jobs

Test the underlying function, not the cron schedule:

// cleanup.test.ts
import { describe, it, expect } from "vitest";
import { cleanupExpiredSessions } from "./cleanup";

describe("cleanup job", () => {
  it("removes expired sessions", async () => {
    // Create some expired sessions first
    await createExpiredSession();
    
    // Call the endpoint directly
    await cleanupExpiredSessions();
    
    // Verify cleanup happened
    const remaining = await countSessions();
    expect(remaining).toBe(0);
  });
});

Mocking External Services

import { describe, it, expect, vi, beforeEach } from "vitest";
import { sendWelcomeEmail } from "./email";

// Mock external API
vi.mock("./external-email-client", () => ({
  send: vi.fn().mockResolvedValue({ success: true }),
}));

describe("email service", () => {
  it("sends welcome email", async () => {
    const result = await sendWelcomeEmail({ userId: "123" });
    expect(result.sent).toBe(true);
  });
});

Test Configuration

Create vite.config.ts (required for ~encore imports):

import { defineConfig } from "vitest/config";
import path from "path";

export default defineConfig({
  resolve: {
    alias: {
      "~encore": path.resolve(__dirname, "./encore.gen"),
    },
  },
  test: {
    globals: true,
    environment: "node",
    include: ["**/*.test.ts"],
    coverage: {
      reporter: ["text", "json", "html"],
    },
  },
});

VS Code Integration

Install the Vitest extension and add to .vscode/settings.json:

{
  "vitest.commandLine": "encore test"
}

Note: For VS Code test explorer, disable file-level parallelism to avoid port conflicts:

// vite.config.ts
export default defineConfig({
  // ...
  test: {
    fileParallelism: false,  // Disable for VS Code
    // ...
  },
});

Re-enable for CI: encore test --fileParallelism=true

Guidelines

  • Use encore test to run tests with infrastructure setup
  • Test API endpoints by calling them directly as functions
  • Service-to-service calls work normally in tests
  • Mock external dependencies (third-party APIs, email services, etc.)
  • Don't mock Encore infrastructure (databases, Pub/Sub) - use the real thing

Install

Install with chainctl
chainctl skill install public/encoredev/testing:latest
Get started with chainctl
View source

Harden your own skills

Bring Chainguard's hardening pipeline to your first-party skills — custom rulesets, automated remediation, full audit trail.

Provenance

Upstream sourcehttps://github.com/encoredev/skills
Upstream commit023e613c4ff8c9152830264d002b09fba527b9a1
OCI reference

skills.cgr.dev/public/github.com/encoredev/encore/testing:latest

License

Apache-2.0

Files

HARDENING.md

LICENSE

SKILL.md


The trusted source for open source

Talk to an expert
PrivacyTerms

Product

Chainguard ContainersChainguard LibrariesChainguard VMsChainguard OS PackagesChainguard ActionsChainguard Agent SkillsIntegrationsPricing
© 2026 Chainguard, Inc. All Rights Reserved.
Chainguard® and the Chainguard logo are registered trademarks of Chainguard, Inc. in the United States and/or other countries.
The other respective trademarks mentioned on this page are owned by the respective companies and use of them does not imply any affiliation or endorsement.