ACATCore.Tests.Shared
February 19, 2026 ยท View on GitHub
Shared testing utilities and base classes for all ACAT test projects.
Overview
This library provides common testing infrastructure including:
- Base test classes with setup/teardown
- Test data builders and generators
- Mock helpers using Moq framework
- Test fixture management
- Enhanced assertion utilities
Components
BaseTest
Base class for all unit tests providing:
- Automatic test directory creation/cleanup
- Performance measurement with Stopwatch
- Test logging utilities
- Common assertions and helpers
Usage:
[TestClass]
public class MyTests : BaseTest
{
[TestMethod]
public void TestSomething()
{
// TestDirectory is automatically created
string testFile = CreateTempFile("test.json", "{}");
// Test code here
WriteTestInfo("Test is running");
// Automatic cleanup happens in base class
}
}
TestDataBuilder
Builder pattern for creating test data:
public class MyDataBuilder : TestDataBuilder<MyData>
{
private string _name = "Default";
private int _value = 0;
public MyDataBuilder WithName(string name)
{
_name = name;
return this;
}
public MyDataBuilder WithValue(int value)
{
_value = value;
return this;
}
public override MyData Build()
{
return new MyData { Name = _name, Value = _value };
}
public override void Reset()
{
_name = "Default";
_value = 0;
}
}
// Usage
var data = new MyDataBuilder()
.WithName("Test")
.WithValue(42)
.Build();
TestDataGenerator
Utilities for generating random test data:
// Generate random strings
string name = TestDataGenerator.RandomString(10);
// Generate random values
int value = TestDataGenerator.RandomInt(1, 100);
bool flag = TestDataGenerator.RandomBool();
string guid = TestDataGenerator.RandomGuid();
// Generate random dates
DateTime date = TestDataGenerator.RandomDate();
// Select random item
string item = TestDataGenerator.RandomItem("A", "B", "C");
// Generate lists
var items = TestDataGenerator.RandomList(() => new MyData(), 10);
MockHelper
Utilities for creating mocks with Moq:
// Create mock logger
var mockLogger = MockHelper.CreateMockLogger<MyClass>();
// Create capturing logger
var capturedMessages = new List<string>();
var mockLogger = MockHelper.CreateCapturingLogger<MyClass>(capturedMessages);
// Create mock logger factory
var mockFactory = MockHelper.CreateMockLoggerFactory();
// Verify logger was called
MockHelper.VerifyLoggerCalled(mockLogger, LogLevel.Information);
MockHelper.VerifyLoggerCalledWithMessage(mockLogger, "Expected message");
// Create strict/loose mocks
var strictMock = MockHelper.CreateStrictMock<IMyInterface>();
var looseMock = MockHelper.CreateLooseMock<IMyInterface>();
TestWorkspace
Isolated workspace for integration tests:
using (var workspace = new TestWorkspace("MyTest"))
{
// Create directories and files
workspace.CreateDirectory("configs");
workspace.CreateFile("configs/settings.json", "{}");
// Check existence
bool exists = workspace.FileExists("configs/settings.json");
// Read files
string content = workspace.ReadFile("configs/settings.json");
// Get paths
string fullPath = workspace.GetPath("configs");
// Automatic cleanup on dispose
}
AssertHelper
Enhanced assertions:
// Collection assertions
AssertHelper.CollectionContainsExactly(actual, "A", "B", "C");
AssertHelper.CollectionContainsAll(actual, "A", "B");
AssertHelper.CollectionDoesNotContain(actual, "X", "Y");
// String assertions
AssertHelper.StringContains(actual, "substring");
AssertHelper.StringDoesNotContain(actual, "bad");
AssertHelper.StringStartsWith(actual, "prefix");
AssertHelper.StringEndsWith(actual, "suffix");
// Range assertions
AssertHelper.InRange(value, 1, 100);
AssertHelper.DateTimeClose(actual, expected, TimeSpan.FromSeconds(1));
AssertHelper.DoubleClose(actual, expected, 0.001);
// Predicate assertions
AssertHelper.All(collection, x => x.IsValid);
AssertHelper.Any(collection, x => x.IsSpecial);
AssertHelper.None(collection, x => x.IsDeleted);
Usage in Test Projects
Add reference to this library in your test project:
<ItemGroup>
<ProjectReference Include="..\ACATCore.Tests.Shared\ACATCore.Tests.Shared.csproj" />
</ItemGroup>
Then use the utilities:
using ACATCore.Tests.Shared;
[TestClass]
public class MyTests : BaseTest
{
[TestMethod]
public void TestWithMocks()
{
// Create mocks
var mockLogger = MockHelper.CreateMockLogger<MyClass>();
var testData = TestDataGenerator.RandomString();
// Create system under test
var sut = new MyClass(mockLogger.Object);
// Act
sut.DoSomething(testData);
// Assert
MockHelper.VerifyLoggerCalled(mockLogger, LogLevel.Information);
AssertHelper.StringContains(sut.Result, testData);
}
}
Best Practices
- Inherit from BaseTest: Use BaseTest for automatic setup/teardown
- Use TestWorkspace: For tests that need file system isolation
- Mock external dependencies: Use MockHelper for creating mocks
- Generate test data: Use TestDataGenerator for random but valid data
- Use descriptive assertions: AssertHelper provides better error messages
- Clean up resources: BaseTest and TestWorkspace handle cleanup automatically
Testing Patterns
Unit Test Pattern
[TestClass]
public class ServiceTests : BaseTest
{
[TestMethod]
public void Method_Scenario_ExpectedBehavior()
{
// Arrange
var mockDependency = MockHelper.CreateMockLogger<Service>();
var sut = new Service(mockDependency.Object);
// Act
var result = sut.DoWork();
// Assert
Assert.IsNotNull(result);
MockHelper.VerifyLoggerCalled(mockDependency, LogLevel.Information);
}
}
Integration Test Pattern
[TestClass]
public class IntegrationTests : BaseTest
{
[TestMethod]
public void Integration_Scenario_ExpectedBehavior()
{
using (var workspace = new TestWorkspace("IntegrationTest"))
{
// Arrange
workspace.CreateFile("config.json", "{}");
var service = new Service(workspace.WorkspaceRoot);
// Act
var result = service.Process();
// Assert
Assert.IsTrue(workspace.FileExists("output.txt"));
}
}
}
Dependencies
- MSTest 3.7.0
- Moq 4.20.72
- Microsoft.Extensions.DependencyInjection 8.0.0
- Microsoft.Extensions.Logging 8.0.0
- FluentValidation 11.9.0
- System.Text.Json 9.0.7