I am in the process of creating a Gradle plugin that starts a separate WireMock process and loads stub mappings for our tests. In order to promote decoupling the WireMock runtime logic from loading stub mappings I am trying to create a separate configuration where developers can add their own stub mappings via external JAR files.
class WireMockPlugin : Plugin<Project> {
override fun apply(project: Project) {
val extension = project.extensions.create("wireMockPlugin", WireMockPluginExtension::class.java)
project.configurations.create("wiremockResources")
project.tasks.register("startWireMock", StartWireMockTask::class.java) {
wireMockPort.set(extension.wireMockPort.convention(9999))
}
[...]
}
}
The plugin has an extension for configuring the port and some shared logic for starting and stopping on a specific port but that is not relevant for my question. The @TaskAction in startWireMock calls a private function for loading all stub mappings from configuration “wiremockResources”:
@TaskAction
protected fun startWireMockTask() {
[...]
loadStubMappings()
val location = project.layout.buildDirectory.file("wiremock").get()
ProcessBuilder()
.directory(project.layout.projectDirectory.asFile)
.command("cmd", "/c", "start", "java", "-jar", getWireMockJar().absolutePath, "--root-dir", location.asFile.absolutePath, "--port", wireMockPort.get().toString())
.start()
}
private fun loadStubMappings() {
project.configurations.getByName("wiremockResources").forEach {
JarFile(it).use { jar ->
jar.entries().asSequence()
.filter { entry -> entry.name.startsWith("stubs/") && entry.name.endsWith(".json") }
.forEach { entry ->
val name = entry.name.substringAfterLast("/")
val content = jar.getInputStream(entry).bufferedReader().use { it.readText() }
project.layout.buildDirectory.file("wiremock/mappings/$name").get().asFile.apply {
parentFile.mkdirs()
writeText(content)
}
}
}
}
}
Unfortunately, I am unable to test this with TestKit (using JUnit), when I add the resource containing some test mappings to my dependencies in configuration wiremockResources, no mappings are loaded:
fun `it should be possible to load external mapping files from JAR`() {
File(tempDir, "build.gradle.kts").apply {
"""
plugins {
`java`
id("<package>.wiremock-plugin")
}
dependencies {
testImplementation("org.wiremock:wiremock-standalone:3.12.1")
wiremockResources("<package>:test-wiremock-mappings:0.1.0-SNAPSHOT")
}
""".trimIndent()
}
startWireMock()
The strangest part of it all is that when I add the same dependency to the plugin logic, like so:
class WireMockPlugin : Plugin<Project> {
override fun apply(project: Project) {
[...]
project.configurations.create("wiremockResources")
project.dependencies.add("wiremockResources", "<package>:test-wiremock-mappings:0.1.0-SNAPSHOT")
[...]
}
It does seem to work fine (the 2 JSON mappings in that externally prepared JAR file in resources/ are loaded perfectly fine). Is this a restriction with TestKit or am I overlooking something here?
Take note: There is no specific output as the process starts fine. I already tried to debug through the loading of the configurations and am under the impression that it might have something to do with the fact that the configuration is not resolved (yet). But even when I call project.configurations.getByName("wiremockResources").resolve()
it doesn’t seem to find any files on the wiremockResources configuration for some reason.