Skip to content

Instantly share code, notes, and snippets.

@libetl
Created July 31, 2020 17:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save libetl/48beff8234a7e034762fa23f6692cb86 to your computer and use it in GitHub Desktop.
Save libetl/48beff8234a7e034762fa23f6692cb86 to your computer and use it in GitHub Desktop.
DatabaseSimulator.kt
import io.mockk.every
import io.mockk.mockk
import java.sql.*
import java.time.ZonedDateTime
import javax.sql.DataSource
object DatabaseSimulator {
val registeredSQLServerMappings = mutableMapOf<String, ResultSet>()
val calledStatements = mutableListOf<String>()
private inline fun <reified T : PreparedStatement> statementFor(sql: String) =
mockk<T>(relaxed = true).also { statement ->
val result = registeredSQLServerMappings.entries
.firstOrNull {
sql.contains(it.key)
}
every {
statement.execute()
} answers {
if (result != null) calledStatements += result.key
result?.value?.fetchSize ?: 0 > 0
}
every {
statement.executeQuery()
} answers {
if (result != null) calledStatements += result.key
result?.value
}
every {
statement.executeQuery(any())
} answers { (_, i) ->
val result1 =
registeredSQLServerMappings.entries
.firstOrNull {
i.args[0].toString().contains(it.key)
}
calledStatements += result1?.key!!
result1?.value
}
every {
statement.moreResults
} returns false
every {
statement.updateCount
} returns -1
every {
statement.resultSet
} returns result?.value
}
fun DataSource.simulateDatabase() {
registeredSQLServerMappings.clear()
calledStatements.clear()
val thisConnection: Connection = mockk<Connection>(relaxed = true).apply {
every {
prepareCall(any())
} answers { (_, i) ->
statementFor(i.args[0].toString())
}
every {
createStatement()
} answers {
statementFor("???")
}
every {
prepareStatement(any())
} answers { (_, i) ->
statementFor(i.args[0].toString())
}
}
apply {
every {
getConnection(any(), any())
} returns thisConnection
every {
getConnection()
} returns thisConnection
}
}
fun List<Map<*, *>?>.toResultSet() = mockk<ResultSet>(relaxed = true).also { set ->
var index = 0
val l = this
val metadata = mockk<ResultSetMetaData>(relaxed = true) {
every {
columnCount
} returns (l.firstOrNull()?.keys?.size ?: 0)
every {
getColumnLabel(any())
} answers { (_, i) ->
(l.firstOrNull()?.keys?.toList() ?: listOf())[
i.args[0] as Int - 1] as String
}
}
every {
set.metaData
} returns metadata
every {
set.fetchSize
} returns l.size
every {
set.next()
} answers {
index++ < l.size
}
every {
set.getObject(any<Int>())
} answers { (_, i) ->
l[index - 1]?.get(
l[index - 1]?.keys?.toList()?.get(i.args[0] as Int - 1))
}
every {
set.getTimestamp(any<Int>())
} answers { (_, i) ->
(l[index - 1]?.get(
l[index - 1]
?.keys?.toList()?.get(i.args[0] as Int - 1))
as ZonedDateTime?)?.let { Timestamp(it.toEpochSecond() * 1000) }
}
every {
set.getString(any<Int>())
} answers { (_, i) ->
l[index - 1]?.get(
l[index - 1]
?.keys?.toList()?.get(i.args[0] as Int - 1)) as String?
}
every {
set.getLong(any<Int>())
} answers { (_, i) ->
l[index - 1]?.get(
l[index - 1]
?.keys?.toList()?.get(i.args[0] as Int - 1)) as Long
}
every {
set.getInt(any<Int>())
} answers { (_, i) ->
l[index - 1]?.get(
l[index - 1]
?.keys?.toList()?.get(i.args[0] as Int - 1)) as Int
}
every {
set.getBoolean(any<Int>())
} answers { (_, i) ->
l[index - 1]?.get(
l[index - 1]
?.keys?.toList()?.get(i.args[0] as Int - 1)) as Boolean
}
every {
set.getTimestamp(any<String>())
} answers { (_, i) ->
Timestamp(((l[index - 1]?.get(
i.args[0].toString()) as ZonedDateTime?)
?.toEpochSecond() ?: 0) * 1000)
}
every {
set.getString(any<String>())
} answers { (_, i) ->
l[index - 1]?.get(i.args[0].toString()) as String?
}
every {
set.getLong(any<String>())
} answers { (_, i) ->
(l[index - 1]?.get(
i.args[0].toString()) ?: 0) as Long
}
every {
set.getInt(any<String>())
} answers { (_, i) ->
(l[index - 1]?.get(
i.args[0].toString()) ?: 0) as Int
}
every {
set.getBoolean(any<String>())
} answers { (_, i) ->
(l[index - 1]?.get(
i.args[0].toString()) ?: false) as Boolean
}
every {
set.getTimestamp(any<String>())
} answers { (_, i) ->
(l[index - 1]?.get(
i.args[0].toString()) as ZonedDateTime?)?.let {
Timestamp(it.toEpochSecond() * 1000) }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment