On this page
🚧 This documentation is work in progress and for an unreleased version of Fresh.
Testing
To ensure that your application works as expected we can write tests. Any aspect of Fresh can be tested as a whole together or in isolation. We use Deno’s built-in test runner to write tests.
Testing middlewares
To test middlewares we’re going to create a
dummy app and return the relevant info we want to check in a custom /
handler.
import { expect } from "@std/expect";
import { App } from "fresh";
const middleware = define.middleware((ctx) => {
ctx.state.text = "middleware text";
return await ctx.next();
});
Deno.test("My middleware - sets ctx.state.text", async () => {
const handler = new App()
.use(middleware)
.get("/", (ctx) => new Response(ctx.state.text))
.handler();
const res = await handler(new Request("http://localhost"));
const text = await res.text();
expect(text).toEqual("middleware text");
});
You can extend this pattern for other middlewares. When you have a middleware that adds a header to the returned response, you can assert against that too.
Testing app wrapper or layouts
Both the app wrapper component and layouts can be tested in the same way.
import { expect } from "@std/expect";
import { App } from "fresh";
function AppWrapper({ Component }) {
return (
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My App</title>
</head>
<body>
<Component />
</body>
</html>
);
}
Deno.test("App Wrapper - renders title and content", async () => {
const handler = new App()
.appWrapper(AppWrapper)
.get("/", (ctx) => ctx.render(<h1>hello</h1>))
.handler();
const res = await handler(new Request("http://localhost"));
const text = await res.text();
expect(text).toContain("My App");
expect(text).toContain("Hello");
});
Same can be done for layouts.
import { expect } from "@std/expect";
import { App } from "fresh";
function MyLayout({ Component }) {
return (
<div>
<h1>My Layout</h1>
<Component />
</div>
);
}
Deno.test("MyLayout - renders heading and content", async () => {
const handler = new App()
.layout("*", MyLayout)
.get("/", (ctx) => ctx.render(<h1>hello</h1>))
.handler();
const res = await handler(new Request("http://localhost"));
const text = await res.text();
expect(text).toContain("My Layout");
expect(text).toContain("Hello");
});
Testing with file routes and islands
File routes are collected by the
Builder
class and not just by
App
alone. We can generate a snapshot and re-use it for
many app instances in our test suite.
// Best to do this once instead of for every test case for
// performance reasons.
const builder = new Builder();
const applySnapshot = await builder.build({ snapshot: "memory" });
function testApp() {
const app = new App()
.get("/", () => new Response("hello"))
.fsRoutes();
// Applies build snapshot to this app instance.
applySnapshot(app);
}
Deno.test("My Test", () => {
const handler = testApp().handler();
const response = await handler(new Request("http://localhost"));
const text = await response.text();
if (text !== "hello") {
throw new Error("fail");
}
});