Files
jdescopingtool/NEW/tests/JdeScoping.DataSync.Tests/Etl/Destinations/DbBulkImportDestinationTests.cs
T

99 lines
3.6 KiB
C#

using System.Data;
using JdeScoping.DataAccess.Interfaces;
using JdeScoping.DataSync.Etl.Destinations;
using NSubstitute;
namespace JdeScoping.DataSync.Tests.Etl.Destinations;
public class DbBulkImportDestinationTests
{
/// <summary>
/// This test documents that column mapping is applied to ignore extra source columns.
/// The actual functionality requires a database connection and is an integration test concept.
/// The implementation fetches destination columns from INFORMATION_SCHEMA.COLUMNS
/// and only maps columns that exist in both source and destination.
/// </summary>
[Fact]
public void WriteAsync_SourceHasExtraColumns_IgnoresExtraColumns_IntegrationTestConcept()
{
// This is an integration test concept -
// The actual behavior verifies that column mappings are applied:
// 1. GetDestinationColumnsAsync fetches columns from INFORMATION_SCHEMA.COLUMNS
// 2. Column mappings only added for columns in destination (case-insensitive)
// 3. Extra source columns are silently ignored during bulk copy
//
// To test this fully, an integration test with a real database is required.
// The unit test here just verifies the component can be constructed.
var factory = Substitute.For<IDbConnectionFactory>();
var dest = new DbBulkImportDestination(factory, "TestTable");
Assert.NotNull(dest);
}
[Fact]
public void Constructor_SetsDestinationName()
{
var factory = Substitute.For<IDbConnectionFactory>();
var dest = new DbBulkImportDestination(factory, "WorkOrder");
Assert.Equal("BulkImport:WorkOrder", dest.DestinationName);
}
[Fact]
public void Constructor_NullFactory_ThrowsArgumentNullException()
{
Assert.Throws<ArgumentNullException>(() => new DbBulkImportDestination(null!, "WorkOrder"));
}
[Fact]
public void Constructor_NullTableName_ThrowsArgumentNullException()
{
var factory = Substitute.For<IDbConnectionFactory>();
Assert.Throws<ArgumentNullException>(() => new DbBulkImportDestination(factory, null!));
}
[Fact]
public void Constructor_EmptyTableName_ThrowsArgumentException()
{
var factory = Substitute.For<IDbConnectionFactory>();
Assert.Throws<ArgumentException>(() => new DbBulkImportDestination(factory, ""));
}
[Theory]
[InlineData(0)] // 0 means default
[InlineData(5000)]
[InlineData(50000)]
public void Constructor_VariousBatchSizes_Succeeds(int batchSize)
{
var factory = Substitute.For<IDbConnectionFactory>();
var dest = new DbBulkImportDestination(factory, "WorkOrder", batchSize: batchSize);
Assert.NotNull(dest);
}
[Fact]
public void Constructor_CustomTimeout_SetsTimeout()
{
// Arrange & Act
var factory = Substitute.For<IDbConnectionFactory>();
var dest = new DbBulkImportDestination(
factory,
"TestTable",
commandTimeoutSeconds: 1800);
// Assert - can't directly test private field, but constructor should accept it
Assert.NotNull(dest);
}
[Fact]
public void Constructor_ZeroTimeout_UsesDefault()
{
// Arrange & Act
var factory = Substitute.For<IDbConnectionFactory>();
var dest = new DbBulkImportDestination(
factory,
"TestTable",
commandTimeoutSeconds: 0);
// Assert
Assert.NotNull(dest);
}
}