Skip to main content
Deno 2 is finally here 🎉️
Learn more

superdeno

HTTP assertions for Deno made easy via superagent.

GitHub tag Test deno doc PRs Welcome GitHub issues GitHub stars GitHub forks SuperDeno License Maintenance HitCount

import { superdeno } from "https://deno.land/x/superdeno@master/mod.ts";
import { opine } from "https://deno.land/x/opine@0.8.0/mod.ts";

const app = opine();

app.get("/user", (req, res) => {
  res.setStatus(200).json({ name: "deno" });
});

superdeno(app)
  .get("/user")
  .expect("Content-Type", /json/)
  .expect("Content-Length", "15")
  .expect(200)
  .end((err, res) => {
    if (err) throw err;
  });

About

The motivation of this module is to provide a high-level abstraction for testing HTTP in Deno, while still allowing you to drop down to the lower-level API provided by superagent.

Installation

This is a Deno module available to import direct from this repo and via the Deno Registry.

Before importing, download and install Deno.

You can then import SuperDeno straight into your project:

import { superdeno } from "https://deno.land/x/superdeno@master/mod.ts";

If you want to use a specific version of SuperDeno, just modify the import url to contain the version:

import { superdeno } from "https://deno.land/x/superdeno@0.3.0/mod.ts";

Or if you want to use a specific commit of SuperDeno, just modify the import url to contain the commit hash:

import { superdeno } from "https://deno.land/x/superdeno@c21f8d6/mod.ts";

Example

You may pass a url string, http.Server, a request handling function, or an object that implements an app.listen() method (which mirrors the http.serve interface) to superdeno() - if SuperDeno identifies that a server is not already listening for connections, then one is bound to an ephemeral port for you so there is no need to keep track of ports.

SuperDeno works with any Deno test framework. Here’s an example with Deno’s built-in test framework, note how you can pass done straight to any of the .expect() calls:

Deno.test("GET /user responds with json", (done) => {
  request(app)
    .get("/user")
    .set("Accept", "application/json")
    .expect("Content-Type", /json/)
    .expect(200, done);
});

Here’s an example of SuperDeno working with the Opine web framework:

import { opine } from "https://deno.land/x/opine@0.8.0/mod.ts";
import { expect } from "https://deno.land/x/expect@9effa6/mod.ts";

Deno.test("it should support regular expressions", (done) => {
  const app = opine();

  app.get("/", (req, res) => {
    res.send("hey");
  });

  superdeno(app)
    .get("/")
    .expect("Content-Type", /^application/)
    .end((err) => {
      expect(err.message).toEqual(
        'expected "Content-Type" matching /^application/, got "text/html; charset=utf-8"'
      );
      done();
    });
});

Here’s an example of SuperDeno working with the Oak web framework:

import { Application, Router } from "https://deno.land/x/oak@v5.0.0/mod.ts";

Deno.test("it should support the Oak framework", (done) => {
  const router = new Router();
  router.get("/", (ctx) => {
    ctx.response.body = "hello";
  });

  const app = new Application();
  app.use(router.routes());
  app.use(router.allowedMethods());

  const controller = new AbortController();
  const { signal } = controller;

  app.addEventListener("listen", ({ hostname, port, secure }) => {
    const protocol = secure ? "https" : "http";
    const url = `${protocol}://${hostname}:${port}`;

    superdeno(url)
      .get("/")
      .expect("hello", () => {
        controller.abort();
        done();
      });
  });

  await app.listen({ port: 0, signal });
});

For further examples, see the tests or the supertest examples for inspiration.

Docs

API

You may use any superagent client (browser) methods and perform assertions in the .end() callback for lower-level needs.

.expect(status[, fn])

Assert response status code.

.expect(status, body[, fn])

Assert response status code and body.

.expect(body[, fn])

Assert response body text with a string, regular expression, or parsed body object.

.expect(field, value[, fn])

Assert header field value with a string or regular expression.

.expect(function(res) {})

Pass a custom assertion function. It’ll be given the response object to check. If the check fails, throw an error.

superdeno(app).get("/").expect(hasPreviousAndNextKeys).end(done);

function hasPreviousAndNextKeys(res) {
  if (!("next" in res.parsedBody)) throw new Error("missing next key");
  if (!("prev" in res.parsedBody)) throw new Error("missing prev key");
}

.end(fn)

Perform the request and invoke fn(err, res).

Notes

This is a port (not fork) of supertest to TypeScript + Deno, which fulfills this motivation currently for Node. This module also includes a XHR sham so superagent client mode can be used directly.

Contributing

Contributing guide


License

This library is a port of supertest whose license and copyrights are available at SUPERTEST_LICENSE in the root of this repository, and covers all files within the source directory which detail that the file is a port.

superdeno is licensed under the MIT License.