diff --git a/Makefile b/Makefile
index 8f4432ae57..43663fe528 100644
--- a/Makefile
+++ b/Makefile
@@ -793,7 +793,6 @@ TEST_BUILTINS_OBJS += test-dump-fsmonitor.o
 TEST_BUILTINS_OBJS += test-dump-split-index.o
 TEST_BUILTINS_OBJS += test-dump-untracked-cache.o
 TEST_BUILTINS_OBJS += test-env-helper.o
-TEST_BUILTINS_OBJS += test-example-decorate.o
 TEST_BUILTINS_OBJS += test-example-tap.o
 TEST_BUILTINS_OBJS += test-find-pack.o
 TEST_BUILTINS_OBJS += test-fsmonitor-client.o
@@ -1335,6 +1334,7 @@ THIRD_PARTY_SOURCES += sha1collisiondetection/%
 THIRD_PARTY_SOURCES += sha1dc/%
 
 UNIT_TEST_PROGRAMS += t-ctype
+UNIT_TEST_PROGRAMS += t-example-decorate
 UNIT_TEST_PROGRAMS += t-mem-pool
 UNIT_TEST_PROGRAMS += t-prio-queue
 UNIT_TEST_PROGRAMS += t-strbuf
diff --git a/decorate.h b/decorate.h
index cdeb17c9df..08af658d34 100644
--- a/decorate.h
+++ b/decorate.h
@@ -3,7 +3,7 @@
 
 /*
  * A data structure that associates Git objects to void pointers. See
- * t/helper/test-example-decorate.c for a demonstration of how to use these
+ * t/unit-tests/t-example-decorate.c for a demonstration of how to use these
  * functions.
  */
 
diff --git a/t/helper/test-example-decorate.c b/t/helper/test-example-decorate.c
deleted file mode 100644
index 8f59f6be4c..0000000000
--- a/t/helper/test-example-decorate.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include "test-tool.h"
-#include "git-compat-util.h"
-#include "object.h"
-#include "decorate.h"
-#include "repository.h"
-
-int cmd__example_decorate(int argc UNUSED, const char **argv UNUSED)
-{
-	struct decoration n;
-	struct object_id one_oid = { {1} };
-	struct object_id two_oid = { {2} };
-	struct object_id three_oid = { {3} };
-	struct object *one, *two, *three;
-
-	int decoration_a, decoration_b;
-
-	void *ret;
-
-	int i, objects_noticed = 0;
-
-	/*
-	 * The struct must be zero-initialized.
-	 */
-	memset(&n, 0, sizeof(n));
-
-	/*
-	 * Add 2 objects, one with a non-NULL decoration and one with a NULL
-	 * decoration.
-	 */
-	one = lookup_unknown_object(the_repository, &one_oid);
-	two = lookup_unknown_object(the_repository, &two_oid);
-	ret = add_decoration(&n, one, &decoration_a);
-	if (ret)
-		BUG("when adding a brand-new object, NULL should be returned");
-	ret = add_decoration(&n, two, NULL);
-	if (ret)
-		BUG("when adding a brand-new object, NULL should be returned");
-
-	/*
-	 * When re-adding an already existing object, the old decoration is
-	 * returned.
-	 */
-	ret = add_decoration(&n, one, NULL);
-	if (ret != &decoration_a)
-		BUG("when readding an already existing object, existing decoration should be returned");
-	ret = add_decoration(&n, two, &decoration_b);
-	if (ret)
-		BUG("when readding an already existing object, existing decoration should be returned");
-
-	/*
-	 * Lookup returns the added declarations, or NULL if the object was
-	 * never added.
-	 */
-	ret = lookup_decoration(&n, one);
-	if (ret)
-		BUG("lookup should return added declaration");
-	ret = lookup_decoration(&n, two);
-	if (ret != &decoration_b)
-		BUG("lookup should return added declaration");
-	three = lookup_unknown_object(the_repository, &three_oid);
-	ret = lookup_decoration(&n, three);
-	if (ret)
-		BUG("lookup for unknown object should return NULL");
-
-	/*
-	 * The user can also loop through all entries.
-	 */
-	for (i = 0; i < n.size; i++) {
-		if (n.entries[i].base)
-			objects_noticed++;
-	}
-	if (objects_noticed != 2)
-		BUG("should have 2 objects");
-
-	clear_decoration(&n, NULL);
-
-	return 0;
-}
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index f6fd0fe491..2d82515f56 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -29,7 +29,6 @@ static struct test_cmd cmds[] = {
 	{ "dump-split-index", cmd__dump_split_index },
 	{ "dump-untracked-cache", cmd__dump_untracked_cache },
 	{ "env-helper", cmd__env_helper },
-	{ "example-decorate", cmd__example_decorate },
 	{ "example-tap", cmd__example_tap },
 	{ "find-pack", cmd__find_pack },
 	{ "fsmonitor-client", cmd__fsmonitor_client },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 868f33453c..bc334183c3 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -23,7 +23,6 @@ int cmd__dump_split_index(int argc, const char **argv);
 int cmd__dump_untracked_cache(int argc, const char **argv);
 int cmd__dump_reftable(int argc, const char **argv);
 int cmd__env_helper(int argc, const char **argv);
-int cmd__example_decorate(int argc, const char **argv);
 int cmd__example_tap(int argc, const char **argv);
 int cmd__find_pack(int argc, const char **argv);
 int cmd__fsmonitor_client(int argc, const char **argv);
diff --git a/t/t9004-example.sh b/t/t9004-example.sh
deleted file mode 100755
index 590aab0304..0000000000
--- a/t/t9004-example.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-test_description='check that example code compiles and runs'
-
-TEST_PASSES_SANITIZE_LEAK=true
-. ./test-lib.sh
-
-test_expect_success 'decorate' '
-	test-tool example-decorate
-'
-
-test_done
diff --git a/t/unit-tests/t-example-decorate.c b/t/unit-tests/t-example-decorate.c
new file mode 100644
index 0000000000..3c856a8cf2
--- /dev/null
+++ b/t/unit-tests/t-example-decorate.c
@@ -0,0 +1,80 @@
+#include "test-lib.h"
+#include "object.h"
+#include "decorate.h"
+#include "repository.h"
+
+struct test_vars {
+	struct object *one, *two, *three;
+	struct decoration n;
+	int decoration_a, decoration_b;
+};
+
+static void t_add(struct test_vars *vars)
+{
+	void *ret = add_decoration(&vars->n, vars->one, &vars->decoration_a);
+
+	if (!check(ret == NULL))
+		test_msg("when adding a brand-new object, NULL should be returned");
+	ret = add_decoration(&vars->n, vars->two, NULL);
+	if (!check(ret == NULL))
+		test_msg("when adding a brand-new object, NULL should be returned");
+}
+
+static void t_readd(struct test_vars *vars)
+{
+	void *ret = add_decoration(&vars->n, vars->one, NULL);
+
+	if (!check(ret == &vars->decoration_a))
+		test_msg("when readding an already existing object, existing decoration should be returned");
+	ret = add_decoration(&vars->n, vars->two, &vars->decoration_b);
+	if (!check(ret == NULL))
+		test_msg("when readding an already existing object, existing decoration should be returned");
+}
+
+static void t_lookup(struct test_vars *vars)
+{
+	void *ret = lookup_decoration(&vars->n, vars->one);
+
+	if (!check(ret == NULL))
+		test_msg("lookup should return added declaration");
+	ret = lookup_decoration(&vars->n, vars->two);
+	if (!check(ret == &vars->decoration_b))
+		test_msg("lookup should return added declaration");
+	ret = lookup_decoration(&vars->n, vars->three);
+	if (!check(ret == NULL))
+		test_msg("lookup for unknown object should return NULL");
+}
+
+static void t_loop(struct test_vars *vars)
+{
+	int i, objects_noticed = 0;
+
+	for (i = 0; i < vars->n.size; i++) {
+		if (vars->n.entries[i].base)
+			objects_noticed++;
+	}
+	if (!check_int(objects_noticed, ==, 2))
+		test_msg("should have 2 objects");
+}
+
+int cmd_main(int argc UNUSED, const char **argv UNUSED)
+{
+	struct object_id one_oid = { { 1 } }, two_oid = { { 2 } }, three_oid = { { 3 } };
+	struct test_vars vars = { 0 };
+
+	vars.one = lookup_unknown_object(the_repository, &one_oid);
+	vars.two = lookup_unknown_object(the_repository, &two_oid);
+	vars.three = lookup_unknown_object(the_repository, &three_oid);
+
+	TEST(t_add(&vars),
+	     "Add 2 objects, one with a non-NULL decoration and one with a NULL decoration.");
+	TEST(t_readd(&vars),
+	     "When re-adding an already existing object, the old decoration is returned.");
+	TEST(t_lookup(&vars),
+	     "Lookup returns the added declarations, or NULL if the object was never added.");
+	TEST(t_loop(&vars), "The user can also loop through all entries.");
+
+	clear_decoration(&vars.n, NULL);
+
+	return test_done();
+}
