Skip to main content

Testing

Unit Testing

Testing a Reboot application typically involves testing the servicers you have implemented.

Python

To write a test, you can use the reboot.aio.tests.Reboot class. This allows you to start your servicer, create a context, and call the method you want to test.

async def asyncSetUp(self) -> None:
self.rbt = Reboot()
await self.rbt.start()

async def asyncTearDown(self) -> None:
await self.rbt.stop()

async def test_hello(self) -> None:
await self.rbt.up(servicers=[HelloServicer])

context = self.rbt.create_external_context(name=f"test-{self.id()}")

hello = Hello.lookup("testing-hello")

await hello.Send(context, message="Hello, World")

response: MessagesResponse = await hello.Messages(context)
self.assertEqual(response.messages, ["Hello, World"])

await hello.Send(context, message="Hello, Reboot!")
await hello.Send(context, message="Hello, Peace of Mind!")
response = await hello.Messages(context)
self.assertEqual(
response.messages,
[
"Hello, World",
"Hello, Reboot!",
"Hello, Peace of Mind!",
],
)

Mocking Secrets

Some servicers may use secrets for connecting to external services or handling sensitive data. You can mock secrets using reboot.aio.secrets.MockSecretSource, which lets you override the secrets with values you provide.

Secrets.set_secret_source(
MockSecretSource(
{
MAILGUN_API_KEY_SECRET_NAME: MAILGUN_API_KEY.encode(),
}
)
)
note

When mocking Secrets, make sure to run the servicer in-process by invoking rbt.up with the in_process mode:

self.config = await self.rbt.up(
servicers=servicers,
# Mocking `Secrets` requires running in process.
in_process=True,
)

TypeScript

For TypeScript, you can use the Reboot class from the @reboot-dev/reboot package to start your servicer, create a context, and call the methods you want to test. With the Node.js built-in test runner use t to call subtests and remember to await on them.

import { Reboot } from "@reboot-dev/reboot";

test("Calling Hello.Send", async (t) => {
let rbt: Reboot;

t.before(async () => {
rbt = new Reboot();
await rbt.start();
await rbt.up([HelloServicer]);
});

t.after(async () => {
await rbt.stop();
});

await t.test("Messages", async (t) => {
const context = rbt.createExternalContext("test");

const hello = Hello.lookup("hello-nodejs");

await t.test("sends a message without throwing", async () => {
await hello.send(context, { message: "Hello, World!" });
});

await t.test("messages response includes correct messages", async () => {
const response = await hello.messages(context);

assert(response.equals({ messages: ["Hello, World!"] }));
});
});
});

If you prefer to write tests in BDD style, you can easily set up Reboot yourself in the test preparations, too.

import { ExternalContext, Reboot } from "@reboot-dev/reboot";

describe("Hello Servicer", async () => {
let context: ExternalContext;
let rbt: Reboot;

before(async () => {
rbt = new Reboot();
await rbt.start();
await rbt.up([HelloServicer]);
context = rbt.createExternalContext("test");
});

after(async () => {
await rbt.stop();
});

describe("Messages", async () => {
let hello: HelloWeakReference;

before(() => {
hello = Hello.lookup("hello-nodejs");
});

it("sends a message without throwing", async () => {
await hello.send(context, { message: "Hello, World!" });
});

it("has correct response for messages", async () => {
const response = await hello.messages(context);

assert(response.equals({ messages: ["Hello, World!"] }));
});
});
});

Calling your endpoint from outside of an app

You are able to call your servicer methods from outside of a Reboot app using the ExternalContext or directly with a HTTP request.