Testing
BulkSharp provides in-memory implementations of all storage and scheduling components, making it straightforward to test operations without external dependencies.
Setup
using BulkSharp;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddBulkSharp(builder => builder
.UseFileStorage(fs => fs.UseInMemory())
.UseMetadataStorage(ms => ms.UseInMemory())
.UseScheduler(s => s.UseImmediate()));
services.AddLogging();
var provider = services.BuildServiceProvider();
Or use the convenience method:
services.AddBulkSharpInMemory();
Key differences from production:
UseInMemory()file storage keeps files in memory (no disk I/O)UseInMemory()metadata storage usesConcurrentDictionaryrepositoriesUseImmediate()scheduler processes operations inline (no background threads)
Unit testing an operation
Test your validation and processing logic directly:
[Fact]
public async Task ValidateRowAsync_InvalidEmail_Throws()
{
var operation = new UserImportOperation();
var metadata = new UserMetadata { RequestedBy = "admin" };
var row = new UserRow { FirstName = "Test", Email = "invalid" };
await Assert.ThrowsAsync<BulkValidationException>(() =>
operation.ValidateRowAsync(row, metadata));
}
Integration testing the full pipeline
Test the complete flow from file upload through processing:
[Fact]
public async Task FullPipeline_ValidCsv_CompletesSuccessfully()
{
var services = new ServiceCollection();
services.AddBulkSharpInMemory();
services.AddLogging();
var provider = services.BuildServiceProvider();
var service = provider.GetRequiredService<IBulkOperationService>();
var processor = provider.GetRequiredService<IBulkOperationProcessor>();
var csv = "FirstName,LastName,Email\nAlice,Smith,alice@test.com\n";
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(csv));
var id = await service.CreateBulkOperationAsync(
"import-users", stream, "test.csv",
new UserMetadata { RequestedBy = "admin" }, "test");
await processor.ProcessOperationAsync(id);
var op = await service.GetBulkOperationAsync(id);
Assert.Equal(BulkOperationStatus.Completed, op!.Status);
Assert.Equal(1, op.SuccessfulRows);
Assert.Equal(0, op.FailedRows);
}
Testing pre-submission validation
[Fact]
public async Task Validate_EmptyMetadata_ReturnsErrors()
{
// ... setup ...
var result = await service.ValidateBulkOperationAsync(
"import-users", "{}", Stream.Null, "test.csv");
Assert.False(result.IsValid);
Assert.NotEmpty(result.MetadataErrors);
}
Next Steps
- Quick Start - Basic setup walkthrough
- Error Handling - Testing error scenarios