CustomAssertions 1.4.0
dotnet add package CustomAssertions --version 1.4.0
NuGet\Install-Package CustomAssertions -Version 1.4.0
<PackageReference Include="CustomAssertions" Version="1.4.0" />
<PackageVersion Include="CustomAssertions" Version="1.4.0" />
<PackageReference Include="CustomAssertions" />
paket add CustomAssertions --version 1.4.0
#r "nuget: CustomAssertions, 1.4.0"
#:package CustomAssertions@1.4.0
#addin nuget:?package=CustomAssertions&version=1.4.0
#tool nuget:?package=CustomAssertions&version=1.4.0
CustomAssertions
A modern, fluent assertion library for .NET that provides type-safe, chainable assertions with comprehensive validation capabilities. Designed to work seamlessly with xUnit, NUnit, and MSTest.
โจ Features
- ๐ Fluent API: Chain multiple assertions together for readable, expressive tests
- ๐ฏ Type-Safe: Strong typing with compile-time validation
- ๐ฆ Comprehensive: Assertions for strings, integers, collections, dates, records, structs, tuples, and more
- ๐งช Test Framework Agnostic: Works with xUnit, NUnit, MSTest
- ๐ Modern C#: Leverages latest C# features (records, pattern matching, nullable types)
- ๐ Well-Documented: Full XML documentation for IntelliSense support
- โก Performant: Minimal overhead with efficient implementation
- ๐ Detailed Error Messages: Clear, descriptive failure messages
๐ฆ Installation
Via NuGet Package Manager
Install-Package CustomAssertions
Via .NET CLI
dotnet add package CustomAssertions
Via PackageReference
<PackageReference Include="CustomAssertions" Version="1.2.0" />
๐ Quick Start
using CustomAssertions.ConcreteModels;
using Xunit;
public class ExampleTests
{
[Fact]
public void StringAssertion_Example()
{
var result = new StringAssertions("Hello, World!")
.NotNullOrEmpty()
.HasMinimumLength(5)
.Contains("World")
.MatchesRegex(@"^Hello.*!")
.Validate();
Assert.True(result);
}
[Fact]
public void IntAssertion_Example()
{
var result = new IntAssertions(42)
.IsPositive()
.IsGreaterThan(10)
.IsLessThan(100)
.IsInRange(1, 50)
.Validate();
Assert.True(result);
}
}
๐ Available Assertions
Type-Specific Assertions
- StringAssertions: null/empty checks, length validations, regex matching, contains/not contains
- IntAssertions: positive/negative/zero, comparisons, range validation
- LongAssertions: 64-bit integer validation, even/odd checks, range operations
- ByteAssertions: byte-specific comparisons and range validation
- DecimalAssertions: high-precision decimal validation, scale checks, financial operations
- FloatingPointAssertions: approximate equality, range, special values (NaN, Infinity)
- BoolAssertions: true/false validation, equality checks
- CharAssertions: letter, digit, case, punctuation, whitespace checks
- GuidAssertions: empty/not empty, version validation, format matching
- EnumAssertions: defined values, flag operations, name validation
- DateTimeAssertions: before/after, date range, weekend checks, component validation
- DateTimeOffsetAssertions: timezone-aware date/time validation, offset checks
- TimeSpanAssertions: duration validation, component checks, approximation
Collection & Complex Type Assertions
- CollectionAssertions: empty/not empty, contains item
- DictionaryAssertions: key/value existence, containment checks
- TupleAssertions: length, item validation, reference equality
- NullableAssertions: has value, conditional validation, value equality
- RecordAssertions: value equality for records, reference checks
- StructAssertions: default value, equality checks
- GenericAssertions: type checks, custom predicates, equality operations
- ExceptionAssertions: exception message, type, inner exception, stack trace validation
๏ฟฝ Aggregate Model Example: Airline Reservation System
CustomAssertions includes a complete Domain-Driven Design (DDD) aggregate model example demonstrating enterprise-level patterns and validation. This airline reservation system showcases:
๐ Architecture Patterns
- Aggregate Root Pattern:
Reservationmanages consistency boundary - Entity Pattern:
Flight,Passenger,Ticketwith identity and lifecycle - Value Object Pattern: Immutable
Ticketwith value semantics - Smart Constructors: Validation at construction time
- Encapsulation: Private setters, controlled mutation
๐ง Model Components
Reservation (Aggregate Root)
var flight = new Flight("AA123", "JFK", "LAX", DateTime.UtcNow.AddDays(7));
var passenger = new Passenger("John Smith", "john.smith@email.com");
var reservation = new Reservation(flight, passenger);
// Automatic ticket issuance upon reservation creation
Assert.NotNull(reservation.Ticket);
Assert.True(reservation.IsActive);
// Cancel reservation (affects ticket state)
reservation.Cancel();
Assert.False(reservation.IsActive);
Flight Entity
var flight = new Flight("AA123", "JFK", "LAX", DateTime.UtcNow.AddDays(7));
// Validation with CustomAssertions
new StringAssertions(flight.FlightNumber)
.NotNullOrEmpty()
.HasMinimumLength(1)
.Validate();
new DateTimeAssertions(flight.DepartureTime)
.IsAfter(DateTime.UtcNow)
.Validate();
Passenger Entity
var passenger = new Passenger("John Smith", "john.smith@email.com");
// Built-in validation
Assert.Equal("John", passenger.FirstName);
Assert.Equal("Smith", passenger.LastName);
// Email validation with CustomAssertions
new StringAssertions(passenger.Email)
.NotNullOrEmpty()
.Contains("@")
.Validate();
Ticket Value Object/Entity
var ticket = reservation.Ticket;
// Verify ticket properties
Assert.Equal(reservation.Id, ticket.ReservationId);
Assert.Equal(flight.FlightNumber, ticket.FlightNumber);
Assert.Equal(passenger.Name, ticket.PassengerName);
// Check ticket validity
new BoolAssertions(ticket.IsValid)
.IsTrue()
.Validate();
โ Comprehensive Test Coverage
The aggregate model includes 29 comprehensive unit tests covering:
- โ Entity Validation: Flight, Passenger, Ticket creation and validation
- โ Aggregate Consistency: Reservation maintains invariants across entities
- โ Business Rules: Cancellation workflow, state transitions
- โ Edge Cases: Null handling, empty values, boundary conditions
- โ Integration: Entity relationships and aggregate boundaries
Test Results: 581 total tests, 29 for aggregate model, 100% pass rate
See CustomAssertions.Tests/ReservationAggregateTests.cs for complete test examples.
๐ก Key Learnings
This aggregate demonstrates:
- Aggregate Boundaries: All changes flow through the aggregate root
- Consistency Enforcement: Ticket automatically issued upon reservation
- Encapsulation: Internal entities accessed only through aggregate
- Validation Patterns: Constructor validation + CustomAssertions for testing
- Immutability: Private setters prevent external mutation
- State Management:
IsActivecomputed from ticket state
๏ฟฝ๐๏ธ Architecture
The library follows these design principles:
- SOLID Principles: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion
- Fluent Interface Pattern: Enables method chaining for readable code
- Template Method Pattern: Base classes define structure, concrete classes implement specifics
- Curiously Recurring Template Pattern (CRTP): Type-safe fluent chaining
๐ง Requirements
- .NET 6.0 or higher (.NET 6, .NET 7, .NET 8, .NET 9 supported)
- C# 10 or higher (for modern language features)
๐ License
This project is licensed under the MIT License - see the LICENSE.txt file for details.
Made with โค๏ธ by Darel Johnson
Copyright ยฉ 2024 Darel Johnson. All rights reserved.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
v1.4.0: Init-Only Properties - All entity classes now use modern C# init-only properties for immutability. Properties can only be set during construction, preventing accidental reassignment. Improved type safety and thread safety. 97%+ Copilot Instructions compliance. All 581 tests passing. See CHANGELOG.md for full details.