Skip to content

Commit 81a1c5a

Browse files
committed
Add Tests for the Progress Listener and Error Handler
1 parent 953b921 commit 81a1c5a

2 files changed

Lines changed: 159 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package de.bytefish.jsqlserverbulkinsert.test;
2+
3+
import org.junit.jupiter.api.BeforeEach;
4+
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.api.TestInstance;
6+
7+
import java.sql.Connection;
8+
import java.sql.DriverManager;
9+
import java.sql.Statement;
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
import java.util.UUID;
13+
import java.util.concurrent.atomic.AtomicInteger;
14+
import java.util.concurrent.atomic.AtomicLong;
15+
import java.util.concurrent.atomic.AtomicReference;
16+
17+
import static de.bytefish.jsqlserverbulkinsert.SqlServerBulkInsert.*;
18+
import static org.junit.jupiter.api.Assertions.*;
19+
20+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
21+
public class SqlServerBulkInsertErrorHandlerTest {
22+
23+
private static final String CONNECTION_STRING =
24+
"jdbc:sqlserver://localhost:14330;databaseName=master;user=sa;password=MyStrongPassw0rd;trustServerCertificate=true;";
25+
26+
record ErrorEntity(UUID id, String name) {}
27+
28+
private static final SqlServerMapper<ErrorEntity> MAPPER = SqlServerMapper.forClass(ErrorEntity.class)
29+
.map("Id", SqlServerTypes.UNIQUEIDENTIFIER.from(ErrorEntity::id))
30+
.map("Name", SqlServerTypes.NVARCHAR.from(ErrorEntity::name));
31+
32+
@BeforeEach
33+
public void setupTable() throws Exception {
34+
try (Connection conn = DriverManager.getConnection(CONNECTION_STRING);
35+
Statement stmt = conn.createStatement()) {
36+
stmt.execute("IF OBJECT_ID('dbo.ErrorTestTable', 'U') IS NOT NULL DROP TABLE dbo.ErrorTestTable;");
37+
stmt.execute("CREATE TABLE dbo.ErrorTestTable (Id UNIQUEIDENTIFIER PRIMARY KEY, Name NVARCHAR(255));");
38+
}
39+
}
40+
41+
@Test
42+
public void testErrorHandlerCapturesConstraintViolation() throws Exception {
43+
// Arrange: Prepare data with a duplicate ID to trigger a Primary Key violation
44+
UUID duplicateId = UUID.randomUUID();
45+
List<ErrorEntity> data = List.of(
46+
new ErrorEntity(duplicateId, "First"),
47+
new ErrorEntity(duplicateId, "Duplicate")
48+
);
49+
50+
AtomicReference<Exception> capturedException = new AtomicReference<>();
51+
52+
SqlServerBulkWriter<ErrorEntity> writer = new SqlServerBulkWriter<>(MAPPER)
53+
.withErrorHandler(capturedException::set);
54+
55+
// Act
56+
try (Connection conn = DriverManager.getConnection(CONNECTION_STRING)) {
57+
BulkInsertResult result = writer.saveAll(conn, "dbo", "ErrorTestTable", data);
58+
59+
// Assert
60+
assertFalse(result.success(), "Bulk insert should fail due to PK violation");
61+
assertNotNull(capturedException.get(), "Error handler should have captured the exception");
62+
assertTrue(capturedException.get().getMessage().contains("Violation of PRIMARY KEY constraint"),
63+
"Exception message should indicate PK violation");
64+
}
65+
}
66+
67+
@Test
68+
public void testErrorHandlerCapturesMissingTableError() throws Exception {
69+
// Arrange
70+
List<ErrorEntity> data = List.of(new ErrorEntity(UUID.randomUUID(), "Test"));
71+
AtomicReference<Exception> capturedException = new AtomicReference<>();
72+
73+
SqlServerBulkWriter<ErrorEntity> writer = new SqlServerBulkWriter<>(MAPPER)
74+
.withErrorHandler(capturedException::set);
75+
76+
// Act
77+
try (Connection conn = DriverManager.getConnection(CONNECTION_STRING)) {
78+
// Try to insert into a non-existing table
79+
BulkInsertResult result = writer.saveAll(conn, "dbo", "NonExistingTable", data);
80+
81+
// Assert
82+
assertFalse(result.success());
83+
assertNotNull(capturedException.get());
84+
assertTrue(capturedException.get().getCause().getMessage().contains("Invalid object name"),
85+
"Exception message should indicate missing table");
86+
}
87+
}
88+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package de.bytefish.jsqlserverbulkinsert.test;
2+
3+
import org.junit.jupiter.api.BeforeEach;
4+
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.api.TestInstance;
6+
7+
import java.sql.Connection;
8+
import java.sql.DriverManager;
9+
import java.sql.Statement;
10+
import java.time.*;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.UUID;
14+
import java.util.concurrent.atomic.AtomicInteger;
15+
import java.util.concurrent.atomic.AtomicLong;
16+
17+
import static de.bytefish.jsqlserverbulkinsert.SqlServerBulkInsert.*;
18+
import static org.junit.jupiter.api.Assertions.*;
19+
20+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
21+
public class SqlServerBulkInsertProgressListenerTest {
22+
23+
private static final String CONNECTION_STRING =
24+
"jdbc:sqlserver://localhost:14330;databaseName=master;user=sa;password=MyStrongPassw0rd;trustServerCertificate=true;";
25+
26+
record SimpleEntity(UUID id, String name) {}
27+
28+
private static final SqlServerMapper<SimpleEntity> MAPPER = SqlServerMapper.forClass(SimpleEntity.class)
29+
.map("Id", SqlServerTypes.UNIQUEIDENTIFIER.from(SimpleEntity::id))
30+
.map("Name", SqlServerTypes.NVARCHAR.from(SimpleEntity::name));
31+
32+
@BeforeEach
33+
public void setupTable() throws Exception {
34+
try (Connection conn = DriverManager.getConnection(CONNECTION_STRING);
35+
Statement stmt = conn.createStatement()) {
36+
stmt.execute("IF OBJECT_ID('dbo.ProgressTestTable', 'U') IS NOT NULL DROP TABLE dbo.ProgressTestTable;");
37+
stmt.execute("CREATE TABLE dbo.ProgressTestTable (Id UNIQUEIDENTIFIER PRIMARY KEY, Name NVARCHAR(255));");
38+
}
39+
}
40+
41+
@Test
42+
public void testProgressListenerIsCalledCorrectly() throws Exception {
43+
// Arrange
44+
int totalRecords = 100;
45+
int notifyEvery = 10;
46+
List<SimpleEntity> data = new ArrayList<>();
47+
for (int i = 0; i < totalRecords; i++) {
48+
data.add(new SimpleEntity(UUID.randomUUID(), "Entry " + i));
49+
}
50+
51+
AtomicInteger callCount = new AtomicInteger(0);
52+
AtomicLong lastProcessedCount = new AtomicLong(0);
53+
54+
SqlServerBulkWriter<SimpleEntity> writer = new SqlServerBulkWriter<>(MAPPER)
55+
.withNotifyAfter(notifyEvery, rowsProcessed -> {
56+
callCount.incrementAndGet();
57+
lastProcessedCount.set(rowsProcessed);
58+
});
59+
60+
// Act
61+
try (Connection conn = DriverManager.getConnection(CONNECTION_STRING)) {
62+
BulkInsertResult result = writer.saveAll(conn, "dbo", "ProgressTestTable", data);
63+
64+
// Assert
65+
assertTrue(result.success());
66+
// Progress should be notified 10 times (100 / 10)
67+
assertEquals(totalRecords / notifyEvery, callCount.get(), "Listener should be called exactly 10 times");
68+
assertEquals(totalRecords, lastProcessedCount.get(), "Last notification should report total record count");
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)