Benday.Common.Testing
2.2.1
dotnet add package Benday.Common.Testing --version 2.2.1
NuGet\Install-Package Benday.Common.Testing -Version 2.2.1
<PackageReference Include="Benday.Common.Testing" Version="2.2.1" />
<PackageVersion Include="Benday.Common.Testing" Version="2.2.1" />
<PackageReference Include="Benday.Common.Testing" />
paket add Benday.Common.Testing --version 2.2.1
#r "nuget: Benday.Common.Testing, 2.2.1"
#:package Benday.Common.Testing@2.2.1
#addin nuget:?package=Benday.Common.Testing&version=2.2.1
#tool nuget:?package=Benday.Common.Testing&version=2.2.1
Benday.Common.Testing
A comprehensive testing library for .NET that streamlines unit testing with XUnit and Moq, featuring a powerful assertion framework with fluent syntax and descriptive error messages.
About
Written by Benjamin Day Pluralsight Author | Microsoft MVP | Scrum.org Professional Scrum Trainer https://www.benday.com https://www.slidespeaker.ai info@benday.com YouTube: https://www.youtube.com/@_benday
Key Features
1. Comprehensive Assertion Framework
The library provides a complete assertion framework that addresses XUnit's lack of descriptive failure messages. All assertions support optional custom messages for better debugging.
Static Assertion Classes
AssertThat- Core assertions for general testing- Equality checks (
AreEqual,AreNotEqual) - Null checks (
IsNull,IsNotNull) - Boolean assertions (
IsTrue,IsFalse) - Type checks (
IsOfType,IsNotOfType) - Reference equality (
AreSame,AreNotSame) - Exception testing (
Throws,DoesNotThrow)
- Equality checks (
AssertThatString- String-specific assertions- Null/empty checks (
IsNullOrEmpty,IsNotNullOrEmpty,IsNullOrWhiteSpace) - String comparison (
StartsWith,EndsWith,Contains) - Pattern matching (
Matcheswith regex support) - Length validation (
HasLength) - Case-insensitive comparisons
- Null/empty checks (
AssertThatCollection- Collection assertions- Empty checks (
IsEmpty,IsNotEmpty) - Count validation (
HasCount) - Element presence (
Contains,DoesNotContain) - Subset/superset validation
- Uniqueness checks (
HasUniqueElements) - Element matching (
AllMatch,AnyMatch)
- Empty checks (
AssertThatNumeric- Numeric assertions- Comparison operators (
IsGreaterThan,IsLessThan, etc.) - Range validation (
IsInRange,IsNotInRange) - Sign checks (
IsPositive,IsNegative,IsZero) - Approximate equality for floating-point numbers
- Special value checks (
IsNotNaN,IsFinite)
- Comparison operators (
Fluent Extension Methods
For more readable tests, use the fluent extension methods:
// Object assertions
actual.ShouldEqual(expected);
actual.ShouldNotBeNull();
actual.ShouldBeOfType<string>();
// String assertions
myString.ShouldNotBeNullOrEmpty()
.ShouldStartWith("Hello")
.ShouldContain("World");
// Collection assertions
myList.ShouldHaveCount(5)
.ShouldContain(expectedItem)
.ShouldHaveUniqueElements();
// Numeric assertions
myValue.ShouldBePositive()
.ShouldBeGreaterThan(0)
.ShouldBeLessThan(100);
Simplified Syntax (New!)
All assertion methods now support optional message parameters. You can write simpler assertions without sacrificing error message quality:
// Traditional syntax with custom message
AssertThat.AreEqual(expected, actual, "Values should match after transformation");
// Simplified syntax - still produces descriptive error messages
AssertThat.AreEqual(expected, actual);
// Fluent syntax (recommended)
actual.ShouldEqual(expected);
2. Test Base Class
TestClassBase- Base class for XUnit test classes- Provides
WriteLine()method that integrates with XUnit's ITestOutputHelper - Simplifies console output in tests
- Provides
3. Mocking Utilities
MockUtility- Streamlines Moq-based testing for dependency injection scenariosCreateInstance<T>()- Automatically creates mocks for all constructor parameters- Returns
MockCreationResult<T>for easy mock management
MockCreationResult<T>- Manages created instances and their mocks- Access the created instance and all generated mocks
- Organize and verify mock interactions
Installation
Install via NuGet Package Manager:
Install-Package Benday.Common.Testing
Or via .NET CLI:
dotnet add package Benday.Common.Testing
Usage Examples
Using the Assertion Framework
public class CalculatorTests : TestClassBase
{
public CalculatorTests(ITestOutputHelper output) : base(output)
{
}
[Fact]
public void Add_TwoNumbers_ReturnsSum()
{
// Arrange
var calculator = new Calculator();
// Act
var result = calculator.Add(2, 3);
// Assert using static methods
AssertThat.AreEqual(5, result);
// Or use fluent syntax (recommended)
result.ShouldEqual(5)
.ShouldBePositive()
.ShouldBeInRange(1, 10);
}
[Fact]
public void Divide_ByZero_ThrowsException()
{
// Arrange
var calculator = new Calculator();
Action divideByZero = () => calculator.Divide(10, 0);
// Assert
divideByZero.ShouldThrow<DivideByZeroException>();
}
}
Using MockUtility for Dependency Injection
public class ServiceTests : TestClassBase
{
public ServiceTests(ITestOutputHelper output) : base(output)
{
}
[Fact]
public void ProcessOrder_ValidOrder_CallsRepository()
{
// Arrange
var mockUtility = new MockUtility();
var mockResult = mockUtility.CreateInstance<OrderService>();
var service = mockResult.Instance;
var order = new Order { Id = 1, Total = 100.00m };
// Setup mock behavior
mockResult.GetMock<IOrderRepository>()
.Setup(x => x.Save(It.IsAny<Order>()))
.Returns(true);
// Act
var result = service.ProcessOrder(order);
// Assert
result.ShouldBeTrue();
// Verify mock was called
mockResult.GetMock<IOrderRepository>()
.Verify(x => x.Save(order), Times.Once);
}
}
Chaining Assertions for Comprehensive Tests
[Fact]
public void ValidateUserData_CompleteProfile_PassesAllValidations()
{
// Arrange
var userData = GetUserData();
// Act & Assert with fluent chaining
userData.Name
.ShouldNotBeNullOrEmpty()
.ShouldStartWith("John")
.ShouldHaveLength(8);
userData.Email
.ShouldMatch(@"^[\w\.-]+@[\w\.-]+\.\w+$")
.ShouldContain("@");
userData.Permissions
.ShouldNotBeEmpty()
.ShouldHaveCount(3)
.ShouldContain("read")
.ShouldHaveUniqueElements();
userData.Age
.ShouldBePositive()
.ShouldBeInRange(18, 120);
}
Why Use Benday.Common.Testing?
Better Error Messages: Unlike standard XUnit assertions, our framework provides descriptive error messages that include expected and actual values, making test failures easier to diagnose.
Fluent Syntax: Chain multiple assertions for more readable and maintainable tests.
Comprehensive Coverage: Specialized assertions for strings, collections, numerics, and more.
Simplified Mocking: MockUtility eliminates boilerplate code when testing classes with dependency injection.
Optional Messages: New overloads allow simpler syntax while maintaining informative error messages.
Requirements
- .NET 8.0, .NET 9.0, .NET 10.0, or .NET Standard 2.1
- XUnit 2.x or higher
- Moq 4.x or higher
Bugs? Suggestions? Contribute?
Got ideas for features you'd like to see? Found a bug? Let us know by submitting an issue. Want to contribute? Submit a pull request.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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 is compatible. 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. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Benday.Common (>= 9.7.0)
- Moq (>= 4.20.72)
- xunit (>= 2.9.3)
-
net10.0
- Benday.Common (>= 9.7.0)
- Moq (>= 4.20.72)
- xunit (>= 2.9.3)
-
net8.0
- Benday.Common (>= 9.7.0)
- Moq (>= 4.20.72)
- xunit (>= 2.9.3)
-
net9.0
- Benday.Common (>= 9.7.0)
- Moq (>= 4.20.72)
- xunit (>= 2.9.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
v2.2.1 - Metadata updates only;
v2.2 - Updated dependencies to include netstandard2.1;
v2.1 - Updated dependencies to .net 10.0;
v2.0 - Major overhaul of assertion methods so that they following a consistent naming pattern; Added new overloads to existing assertion methods to not require custom messages;
v1.5 - Added assert utility methods;
v1.4 - Changed the way MockUtility and MockCreationResult work to allow for optional mock configuration before instance creation;
v1.3 - Unpublishing fluent assertions for xUnit from this package...for now;
v1.2 - Added fluent assertions for xUnit to the package;
v1.1 - Added base class functionality for reading sample data files during tests; Removed dependency on FluentAssertions;
v1.0 - Base class for xunit tests; MockUtility for streamlining testing with Moq;