Testing Configs

Test config code at the same layer where it can break: codecs, mappings, migrations, merge behavior, and backend round trips.

Test Codecs Directly

@Test
void endpointCodecRoundTrips() {
  var codecs = new ConfigCodecRegistry()
    .register(Endpoint.class, endpointCodec());

  var node = codecs.encode(new Endpoint("localhost", 25565));
  var decoded = codecs.decode(node, Endpoint.class);

  assertEquals(new Endpoint("localhost", 25565), decoded);
}

Codec tests should check structure and failure behavior. Avoid tying tests to incidental wording in comments unless comments are the feature under test.

Test Defaults

@Test
void staticDefaultsIncludeComments() {
  var definition = StaticConfigDefinition.from(ServerOptions.class);
  var defaults = definition.defaults(new ConfigCodecRegistry());

  var port = defaults.find("server.port").orElseThrow();

  assertEquals(25565, port.asInt().orElseThrow());
  assertFalse(port.comment().isEmpty());
}

Default tests are useful when annotations or static properties are the source of truth for generated files.

Test Migrations

@Test
void migrationRenamesBindToHost() {
  var document = ConfigDocument.empty()
    .set("server.bind", "127.0.0.1");

  MigrationRegistry.builder()
    .addMigration(ConfigMigration.builder()
      .version(1)
      .action(config -> Migrations.rename(config, "server.bind", "server.host"))
      .build())
    .build()
    .migrate(document);

  assertEquals("127.0.0.1", document.find("server.host").flatMap(ConfigNode::asString).orElseThrow());
  assertTrue(document.find("server.bind").isEmpty());
}

Migration tests should start from old document shapes and assert the new shape.

Test Format Round Trips

@Test
void yamlRoundTripKeepsComment() {
  var loader = YamlConfigFormat.INSTANCE.loader();
  var document = ConfigDocument.empty()
    .set("server.port", 25565);

  document.root()
    .getOrCreate(ConfigPath.parse("server.port"))
    .setComment(ConfigComment.builder()
      .addLeading(ConfigCommentLine.builder()
        .text("Public listener port.")
        .type(ConfigCommentType.BLOCK)
        .marker(ConfigCommentMarker.HASH)
        .build())
      .build());

  var output = new StringWriter();
  loader.save(document, output);

  var loaded = loader.load(new StringReader(output.toString()));
  assertEquals(List.of("Public listener port."), loaded.find("server.port").orElseThrow().comment().leadingText());
}

Round-trip tests should be scoped to backend features that matter to your application.

Test Environment Overrides With Explicit Maps

var overrides = EnvironmentOverrides.builder()
  .environmentPrefix("app")
  .propertyPrefix("app")
  .putAllEnvironment(Map.of("APP_SERVER_PORT", "25566"))
  .build();

overrides.applyTo(document);

Explicit maps avoid depending on the test process environment.

Search Documentation