Testing With Nullables
“Nullables” are a novel technique for isolating production code from external systems and state. Although they also have production uses, they’re particularly valuable for creating fast, reliable tests. This page connects to you resources for using Nullables in your code.
Testing Without Mocks: A Pattern Language
Read this in-depth article for everything you need to know about Nullables and their related patterns. It’s a long article, but don’t be intimidated by its size. It’s broken up into bite-sized pieces with lots of code examples.
If you’d prefer to start with something smaller, check out A Light Introduction to Nullables.
Video Overview
The following video was created to announce my “Testing Without Mocks” training course, but it also does a great job of explaining what Nullables are and why they’re valuable. It’s nice and short: less than five minutes.
Training
Learn how to use Nullables in this live online training course on April 11th and 12th. Register here.
To be notified about upcoming “Testing Without Mocks” training courses, send an email with the subject “Subscribe” to nullables-training+
For private training, contact me directly.
Nullables Livestream with Ted M. Young
In this weekly livestream series, which is currently ongoing, I pair up with Ted M. Young, aka jitterted. We look at Nullables and A-Frame Architecture as an alternative to Mocks, Spies, and Hexagonal Architecture. Each episode combines a healthy dose of architecture and design discussion with practical, hands-on coding.
TDD Lunch and Learn Screencast
This weekly screencast, which ran from May to September 2020, uses test-driven development (TDD) to develop a microservice and accompanying command-line application from scratch. Each episode focuses on a new challenge.
The series emphasizes real-world TDD, with a strong focus on “hard” problems such as networking and logging. Many of the episodes involve Nullables and other “Testing Without Mocks” patterns. If you’ve learned the basics of TDD and want to see how it works in the real world, this series is the perfect next step.
Examples
This is what Nullable-based tests look like:
// Example tests (JavaScript + Node.js)
import assert from "assert";
import CommandLine from "./infrastructure/command_line";
import App from "./app";
describe("App", () => {
it("reads command-line argument, transform it with ROT-13, and writes result", () => {
const { output } = run({ args: [ "my input" ] }); // Signature Shielding, Configurable Responses
assert.deepEqual(output.data, [ "zl vachg\n" ]; // Output Tracking
});
it("writes usage when no argument provided", () => {
const { output } = run({ args: [] }); // Signature Shielding, Configurable Responses
assert.deepEqual(output.data, [ "Usage: run text_to_transform\n" ]); // Output Tracking
});
it("complains when too many command-line arguments provided", () => {
const { output } = run({ args: [ "a", "b" ] }); // Signature Shielding, Configurable Responses
assert.deepEqual(output.data, [ "too many arguments\n" ]); // Output Tracking
});
function run({ args = [] } = {}) { // Signature Shielding
const commandLine = CommandLine.createNull({ args }); // Nullable, Infrastructure Wrapper, Configurable Responses
const output = commandLine.trackOutput(); // Output Tracking
const app = new App(commandLine);
app.run();
return { output }; // Signature Shielding
}
});
Find more examples here:
Testing Without Mocks: A Pattern Language. This in-depth article is chock-full of examples and other details.
Simple example. The complete source code for the above example. (JavaScript or TypeScript with Node.js)
Complex example. The blinged-out version of the above example. A web application and microservice that performs ROT-13 encoding. Production-grade code with error handling, logging, timeouts, and request cancellation. (JavaScript or TypeScript with Node.js)