Skip to content

Commit 92eb39e

Browse files
committed
Improve withConnection unit tests
1 parent c509fe9 commit 92eb39e

File tree

1 file changed

+100
-42
lines changed

1 file changed

+100
-42
lines changed

src/test/kotlin/com/github/michaelbull/jdbc/ConnectionTest.kt

Lines changed: 100 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import com.github.michaelbull.jdbc.context.CoroutineConnection
44
import com.github.michaelbull.jdbc.context.CoroutineDataSource
55
import com.github.michaelbull.jdbc.context.connection
66
import io.mockk.every
7+
import io.mockk.just
78
import io.mockk.mockk
9+
import io.mockk.runs
810
import io.mockk.verify
911
import kotlinx.coroutines.ExperimentalCoroutinesApi
1012
import kotlinx.coroutines.test.runBlockingTest
1113
import org.junit.jupiter.api.Assertions.assertEquals
12-
import org.junit.jupiter.api.Assertions.assertNotEquals
13-
import org.junit.jupiter.api.Assertions.assertNotNull
1414
import org.junit.jupiter.api.Test
1515
import java.sql.Connection
1616
import java.sql.SQLException
@@ -19,100 +19,158 @@ import javax.sql.DataSource
1919
@ExperimentalCoroutinesApi
2020
class ConnectionTest {
2121

22-
private val openConnection = mockk<Connection>("OpenConnection", relaxed = true) {
23-
every { isClosed } returns false
24-
}
25-
26-
private val closedConnection = mockk<Connection>("ClosedConnection", relaxed = true) {
27-
every { isClosed } returns true
28-
}
22+
@Test
23+
fun `withConnection adds new connection to context if no connection in context`() {
24+
val newConnection = mockk<Connection> {
25+
every { schema } returns "new"
26+
every { close() } just runs
27+
}
2928

30-
private val dataSource = mockk<DataSource>(relaxed = true).apply {
31-
every { connection } returns openConnection
32-
}
29+
val dataSource = mockk<DataSource> {
30+
every { connection } returns newConnection
31+
}
3332

34-
@Test
35-
fun `withConnection should add new connection to context if absent`() {
3633
val context = CoroutineDataSource(dataSource)
3734

3835
runBlockingTest(context) {
39-
withConnection {
40-
assertNotNull(coroutineContext.connection)
36+
val actual = withConnection {
37+
coroutineContext.connection.schema
4138
}
39+
40+
assertEquals(newConnection.schema, actual)
4241
}
4342
}
4443

4544
@Test
46-
fun `withConnection should add new connection to context if existing is closed`() {
47-
val coroutineConnection = CoroutineConnection(closedConnection)
48-
val context = CoroutineDataSource(dataSource) + coroutineConnection
45+
fun `withConnection adds new connection to context if existing connection isClosed returns true`() {
46+
val existingConnection = mockk<Connection> {
47+
every { schema } returns "existing"
48+
every { isClosed } returns true
49+
}
50+
51+
val newConnection = mockk<Connection> {
52+
every { schema } returns "new"
53+
every { close() } just runs
54+
}
55+
56+
val dataSource = mockk<DataSource> {
57+
every { connection } returns newConnection
58+
}
59+
60+
val context = CoroutineDataSource(dataSource) + CoroutineConnection(existingConnection)
4961

5062
runBlockingTest(context) {
51-
withConnection {
52-
assertNotNull(coroutineContext.connection)
53-
assertNotEquals(coroutineConnection, coroutineContext.connection)
63+
val actual = withConnection {
64+
coroutineContext.connection.schema
5465
}
66+
67+
assertEquals(newConnection.schema, actual)
5568
}
5669
}
5770

5871
@Test
59-
fun `withConnection should add new connection to context if isClosed check throws exception`() {
60-
val coroutineConnection = CoroutineConnection(openConnection)
61-
val context = CoroutineDataSource(dataSource) + coroutineConnection
72+
fun `withConnection adds new connection to context if existing connection isClosed throws exception`() {
73+
val existingConnection = mockk<Connection> {
74+
every { schema } returns "existing"
75+
every { isClosed } throws SQLException()
76+
}
77+
78+
val newConnection = mockk<Connection> {
79+
every { schema } returns "new"
80+
every { close() } just runs
81+
}
6282

63-
every { openConnection.isClosed } throws SQLException()
83+
val dataSource = mockk<DataSource> {
84+
every { connection } returns newConnection
85+
}
86+
87+
val context = CoroutineDataSource(dataSource) + CoroutineConnection(existingConnection)
6488

6589
runBlockingTest(context) {
66-
withConnection {
67-
assertNotEquals(coroutineConnection, coroutineContext.connection)
90+
val actual = withConnection {
91+
coroutineContext.connection.schema
6892
}
93+
94+
assertEquals(newConnection.schema, actual)
6995
}
7096
}
7197

7298
@Test
73-
fun `withConnection should reuse existing connection if still open`() {
74-
val coroutineConnection = CoroutineConnection(openConnection)
75-
val context = CoroutineDataSource(dataSource) + coroutineConnection
99+
fun `withConnection reuses existing connection in context if not closed`() {
100+
val existing = mockk<Connection> {
101+
every { schema } returns "existing"
102+
every { isClosed } returns false
103+
}
104+
105+
val dataSource = mockk<DataSource>()
106+
val context = CoroutineDataSource(dataSource) + CoroutineConnection(existing)
76107

77108
runBlockingTest(context) {
78-
withConnection {
79-
assertEquals(coroutineConnection, coroutineContext.connection)
109+
val actual = withConnection {
110+
coroutineContext.connection.schema
80111
}
112+
113+
assertEquals(existing.schema, actual)
81114
}
82115
}
83116

84117
@Test
85-
fun `withConnection should close connection if new one created`() {
118+
fun `withConnection closes connection if added to context`() {
119+
val newConnection = mockk<Connection> {
120+
every { schema } returns "new"
121+
every { close() } just runs
122+
}
123+
124+
val dataSource = mockk<DataSource> {
125+
every { connection } returns newConnection
126+
}
127+
86128
val context = CoroutineDataSource(dataSource)
87129

88130
runBlockingTest(context) {
89131
withConnection { }
90132
}
91133

92-
verify(exactly = 1) { openConnection.close() }
134+
verify(exactly = 1) { newConnection.close() }
93135
}
94136

95137
@Test
96-
fun `withConnection should ignore failure when closing connection`() {
97-
val context = CoroutineDataSource(dataSource)
138+
fun `withConnection ignores SQLExceptions when closing connection added to context`() {
139+
val newConnection = mockk<Connection> {
140+
every { schema } returns "new"
141+
every { close() } throws SQLException()
142+
}
98143

99-
every { openConnection.close() } throws SQLException()
144+
val dataSource = mockk<DataSource> {
145+
every { connection } returns newConnection
146+
}
147+
148+
val context = CoroutineDataSource(dataSource)
100149

101150
runBlockingTest(context) {
102151
withConnection { }
103152
}
104153

105-
verify(exactly = 1) { openConnection.close() }
154+
verify(exactly = 1) { newConnection.close() }
106155
}
107156

108157
@Test
109-
fun `withConnection should not close connection if reusing existing connection`() {
110-
val context = CoroutineDataSource(dataSource) + CoroutineConnection(openConnection)
158+
fun `withConnection does not close connection if connection was not added to context`() {
159+
val existing = mockk<Connection> {
160+
every { schema } returns "existing"
161+
every { isClosed } returns false
162+
}
163+
164+
val dataSource = mockk<DataSource> {
165+
every { connection } returns existing
166+
}
167+
168+
val context = CoroutineDataSource(dataSource) + CoroutineConnection(existing)
111169

112170
runBlockingTest(context) {
113171
withConnection { }
114172
}
115173

116-
verify(exactly = 0) { openConnection.close() }
174+
verify(exactly = 0) { existing.close() }
117175
}
118176
}

0 commit comments

Comments
 (0)