@@ -4,13 +4,13 @@ import com.github.michaelbull.jdbc.context.CoroutineConnection
44import com.github.michaelbull.jdbc.context.CoroutineDataSource
55import com.github.michaelbull.jdbc.context.connection
66import io.mockk.every
7+ import io.mockk.just
78import io.mockk.mockk
9+ import io.mockk.runs
810import io.mockk.verify
911import kotlinx.coroutines.ExperimentalCoroutinesApi
1012import kotlinx.coroutines.test.runBlockingTest
1113import org.junit.jupiter.api.Assertions.assertEquals
12- import org.junit.jupiter.api.Assertions.assertNotEquals
13- import org.junit.jupiter.api.Assertions.assertNotNull
1414import org.junit.jupiter.api.Test
1515import java.sql.Connection
1616import java.sql.SQLException
@@ -19,100 +19,158 @@ import javax.sql.DataSource
1919@ExperimentalCoroutinesApi
2020class 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