Skip to content

Testing Specifications

Specifications are highly testable because they encapsulate logic in a reusable way. Here are examples of how to test them:

csharp
public class ProductSpecificationTests
{
    [Fact]
    public void IsInStock_WhenQuantityIsGreaterThanZero_ShouldReturnTrue()
    {
        // Arrange
        var product = new Product { AvailableQuantity = 5 };
        var specification = ProductSpecification.IsInStock;

        // Act
        bool result = specification.IsSatisfiedBy(product);

        // Assert
        Assert.True(result);
    }

    [Fact]
    public void IsInStock_WhenQuantityIsZero_ShouldReturnFalse()
    {
        // Arrange
        var product = new Product { AvailableQuantity = 0 };
        var specification = ProductSpecification.IsInStock;

        // Act
        bool result = specification.IsSatisfiedBy(product);

        // Assert
        Assert.False(result);
    }

    [Theory]
    [InlineData(10, 50, 30, true)]
    [InlineData(10, 50, 5, false)]
    [InlineData(10, 50, 60, false)]
    public void InPriceRange_ShouldReturnExpectedResult(
        decimal minPrice, decimal maxPrice, decimal actualPrice, bool expected)
    {
        // Arrange
        var product = new Product { Price = actualPrice };
        var specification = ProductSpecification.InPriceRange(minPrice, maxPrice);

        // Act
        bool result = specification.IsSatisfiedBy(product);

        // Assert
        Assert.Equal(expected, result);
    }
}
csharp
public class ProductSpecificationIntegrationTests : IDisposable
{
    private readonly IDbQuerySessionFactory _sessionFactory;

    public ProductSpecificationIntegrationTests()
    {
        // Setup test database and session factory
        _sessionFactory = CreateTestSessionFactory();
    }

    [Fact]
    public async Task Query_WithIsInStockSpecification_ShouldReturnOnlyInStockProducts()
    {
        // Arrange
        await using var session = _sessionFactory.Create();
        var specification = ProductSpecification.IsInStock;

        // Act
        var query = session.Query(specification);
        var products = await query.ToListAsync();

        // Assert
        Assert.All(products, p => Assert.True(p.AvailableQuantity > 0));
    }

    public void Dispose()
    {
        // Cleanup test database
    }
}
csharp
public class CombinedSpecificationTests
{
    [Fact]
    public void AndSpecification_WhenBothSatisfied_ShouldReturnTrue()
    {
        // Arrange
        var product = new Product
        {
            AvailableQuantity = 10,
            Price = 25.0m
        };

        var specification = ProductSpecification.IsInStock
            .And(ProductSpecification.InPriceRange(10.0m, 50.0m));

        // Act
        bool result = specification.IsSatisfiedBy(product);

        // Assert
        Assert.True(result);
    }

    [Fact]
    public void NotSpecification_ShouldInvertResult()
    {
        // Arrange
        var product = new Product { AvailableQuantity = 0 };
        var specification = ProductSpecification.IsInStock.Not();

        // Act
        bool result = specification.IsSatisfiedBy(product);

        // Assert
        Assert.True(result);
    }
}

Released under the MIT License.