Network Plugin

The network plugin allows you to capture and explore the network traffic in your project. It supports popular KMP networking libraries and is easily extended with support for custom HTTP clients.
Ktor v3
Monitor Ktor v3 client requests:
Add dependency:
dependencies {
implementation(TestbenchDeps.networkClientKtor)
// or manually
implementation("org.drewcarlson.testbench:network-client-ktor:0.0.9-SNAPSHOT")
}
Configure the plugin:
// Set up the testbench plugin
val networkPlugin = KtorNetworkClientPlugin()
// Add it to the testbench client
val testbenchClient =
TestbenchClient(
plugins = listOf(networkPlugin),
)
// Install the Ktor Plugin
val httpClient = HttpClient {
networkPlugin.install(this)
}
OkHttp
Monitor OkHttp requests:
Add dependency:
dependencies {
implementation(TestbenchDeps.networkClientOkhttp)
// or manually
implementation("org.drewcarlson.testbench:network-client-okhttp:0.0.9-SNAPSHOT")
}
Configure the plugin:
// Set up the testbench plugin
val networkPlugin = OkHttpNetworkClientPlugin()
// Add it to the testbench client
val testbenchClient =
TestbenchClient(
plugins = listOf(networkPlugin),
)
// Install the OkHttp interceptor
val okhttp = OkHttpClient.Builder()
.addInterceptor(networkPlugin)
.build()
Custom HTTP Client
Add dependency on the core plugin library:
dependencies {
implementation(TestbenchDeps.networkClientCore)
// or manually
implementation("org.drewcarlson.testbench:network-client-core:0.0.9-SNAPSHOT")
}
Implement a NetworkPlugin using your HTTP clients middleware or logging APIs:
class CustomNetworkClientPlugin :
NetworkPlugin(),
ClientPlugin<Unit, NetworkPluginMessage> {
private val messageQueue = Channel<NetworkPluginMessage>(
capacity = Int.MAX_VALUE,
onBufferOverflow = BufferOverflow.DROP_OLDEST,
)
override val outgoingMessages: Flow<NetworkPluginMessage> = messageQueue.receiveAsFlow()
override suspend fun handleMessage(message: Unit) = Unit
suspend fun sendMessage(message: NetworkPluginMessage) {
messageQueue.emit(message)
}
}
val networkPlugin = CustomNetworkClientPlugin()
val customHttpClient = HttpClientBuilder()
// Send update for a new request that is starting
.onRequest { request ->
// Add ID to track response updates
request.attribute["debug-id"] = uuid()
val message = NetworkRequestMessage(
id = request.attribute["debug-id"],
url = request.urlString,
method = request.method,
headers = request.headers,
initiatedAt = request.startedAt,
body = request.bodyTextOrNull(),
)
networkPlugin.sendMessage(message)
}
.onResponse { response ->
// Send update for completed response
NetworkResponseMessage.Completed(
id = response.attributes["debug-id"],
headers = response.headers,
status = response.status,
body = response.bodyAsText(),
)
messageQueue.trySend(message)
}
.onError { error ->
val message = when (error) {
// Send update for cancelled request
is RequestCancelled ->
NetworkResponseMessage.Cancelled(
id = error.request.attributes["debug-id"],
sent = true, // Set if the request was actually initiated
)
// Send update for a failed request
else ->
NetworkResponseMessage.Failed(
id = id,
message = error.stackTraceToString(),
)
}
messageQueue.trySend(message)
}
.build()