Testkit

Lazyval provides a testkit which can run either the Java Annotation Processor toolchain or the KSP2 toolchain together with the Kotlin compiler.

var tmpDir = Path.of(System.getProperty("java.io.tmpdir")); (1)
var scenario = Scenario.Java.of("scenarios/java/MyTestLazyval.java") (2)
    .withDependencies(new Dependency("some.groupId", "some.artifactId", "1.0.0")); (3)
var result = Testkit.java() (4)
    .run(tmpDir, scenario); (5)
1 The testkit needs a folder where it can put generated-sources, as well as compiled classes. Usually you would use your test-framework to get a temporary folder for the test execution.
2 Define the scenario with the main source file, as well as any additionally required sources. The sources must be located in your classpath meaning src/test/resources.
3 Add the dependency which is required for your SPI implementation. Remember, if the required classpath is not available, Lazyval will not trigger any generation for that SPI.
4 Initialize the testkit either with java() when you are targeting Lazyvals Java Annotation Processor or kotlin() when targeting KSP2.
5 Run the scenario and verify the result.

Using Predefined Scenarios

The testkit ships a collection of predefined valid scenarios for both Java and Kotlin. For instance, Scenario.Java.Quantity uses a primitive int which might need boxing in some generators (like JPA AttributeConverter)

in general, SPI providers should test against Scenario.Java.All and Scenario.Kotlin.All to make sure the generator can handle all cases Lazyval will throw at it.
the predefined scenarios need still to be configured with the required generator Dependency in order to yield generator artifacts.

Data-Driven Samples

See the Spock Example or Kotest Example for how to set up a data-driven test scenario using the predefined scenarios.

Verifying Results

The testkit defines result record types for the interfaces Testresult.Java and Testresult.Kotlin. The motivation for using records is that they are easily comparable by all kinds of testframeworks without requiring any additional and specific matchers.

Spock uses its PowerAssert
result == new Testresult.Java.Success("LazyvalMapper.java")
Kotest uses shouldEqual
result shouldEqual Testresult.Kotlin.Success("LazyvalMapper.java")
JUnit uses assertEquals
assertEquals(new Testresult.Java.Success("LazyvalMapper.java"), result);

Logging

The testkit captures all logs from the toolchains and forwards them to SLF4J. To see any output, the test-classpath must provide any SLF4J implementation (like slf4j-simple), since the testkit only depends on slf4j-api.

Dependency on Eclipse Collections

Eclipse Collections are used throughout the testkit since they provide stronger guarantees compared to Collections.unmodifiableXXX which also aligns better with how Kotlin treats Collections.

Dependency Resolution

The testkit mimics Maven when downloading and caching dependencies, but it does not read any Maven-specific configuration files (settings.xml, pom.xml).

By default, dependencies are downloaded from https://repo1.maven.org/maven2/ and stored at <user-home>/.m2/repository.

This might not work in corporate environments which might block direct access to Maven Central or use an internal Registry (Nexus). Or users might have reconfigured their cache-location. In this case you can override the defaults via JVM system properties:

Property Description

lazyval.testkit.maven-repo

Absolute path to the folder where the dependencies should be cached, (usually Maven cache location)

lazyval.testkit.maven-mirror

Base-URL of the repository instance or mirror to be used. Note that this must provide the maven2 url path to resolve dependencies like https://acme.com/maven2/<groupid>/<artifactid>/<version>;

Repository Authentication

In case your repository server does not allow anonymous access, you can use Basic-Auth by specifying the following environment variables:

  • LAZYVAL_TESTKIT_MIRROR_USERNAME

  • LAZYVAL_TESTKIT_MIRROR_PASSWORD