A fluent assertion library that makes your tests readable, intuitive, and expressive with zero runtime dependencies. Transform your test code into self-documenting specifications.
Designed specifically for .NET developers who want readable, expressive tests without the complexity.
Write tests that read like natural language with intuitive fluent API design and method chaining.
No external dependencies means cleaner package references and faster build times for your test projects.
Detailed error messages with expected vs actual values help you debug test failures quickly.
Install Noundry.Assertive and start writing fluent, readable test assertions.
Or add to your .csproj:
using Noundry.Assertive;
using Xunit;
public class ProductTests
{
[Fact]
public void CreateProduct_ShouldReturnValidProduct()
{
// Act
var product = new Product("Laptop", 999.99m, 10);
// Assert - Fluent and readable
product.Assert()
.IsNotNull()
.IsOfType<Product>()
.Satisfies(p => p.Name == "Laptop", "Product name should match")
.Satisfies(p => p.Price > 0, "Price should be positive");
}
}
Comprehensive assertion methods for all your testing scenarios.
Ensures the object isn't null
Ensures the object is null
Checks equality with expected value
Checks inequality with specified value
Checks object's exact type
Ensures object isn't the specified type
Ensures collection contains the item
Ensures collection doesn't contain item
Ensures collection is empty
Ensures collection is not empty
Ensures collection has specific count
Checks if value is within range (inclusive)
Validates custom conditions
Ensures object doesn't match condition
Adds context to error messages
Learn from practical examples showing Noundry.Assertive in action across different testing scenarios.
Test string values, null checks, and basic equality with fluent, readable assertions.
[Fact]
public void ProcessMessage_ShouldReturnFormattedString()
{
// Arrange
var input = "Hello, World!";
// Act
var result = messageService.ProcessMessage(input);
// Assert - Fluent and readable
result.Assert()
.IsNotNull()
.IsOfType<string>()
.IsEqualTo("HELLO, WORLD!")
.Satisfies(s => s.Length > 5, "Should have content");
// Test null scenarios
string nullResult = null;
nullResult.Assert().IsNull();
}
Validate numeric values, ranges, and mathematical operations with expressive assertions.
[Fact]
public void CalculateDiscount_ShouldReturnValidDiscount()
{
// Arrange
var originalPrice = 100m;
var discountPercent = 20;
// Act
var discountedPrice = calculator.ApplyDiscount(originalPrice, discountPercent);
// Assert - Numeric validations
discountedPrice.Assert()
.IsNotNull()
.IsOfType<decimal>()
.IsEqualTo(80m)
.IsInRange(0m, originalPrice)
.Satisfies(price => price < originalPrice,
"Discounted price should be less than original");
}
Test collections, lists, and arrays with intuitive assertions for common scenarios.
[Fact]
public void GetActiveUsers_ShouldReturnFilteredList()
{
// Arrange
var users = CreateTestUsers();
// Act
var activeUsers = userService.GetActiveUsers(users);
// Assert - Collection validations
activeUsers.Assert()
.IsNotNull()
.IsNotEmpty<User>()
.HasCount<User>(3)
.Contains(users.First(u => u.IsActive))
.DoesNotContain(users.First(u => !u.IsActive));
// Validate each user in collection
foreach (var user in activeUsers)
{
user.Assert()
.Satisfies(u => u.IsActive, "User should be active");
}
}
Test complex objects with contextual information and custom validation predicates.
[Fact]
public void CreateOrder_ShouldReturnValidOrder()
{
// Arrange
var customer = new Customer { Id = 1, Name = "John Doe" };
var items = CreateTestItems();
// Act
var order = orderService.CreateOrder(customer, items);
// Assert with context
order.Assert()
.WithContext("Order creation validation")
.IsNotNull()
.IsOfType<Order>()
.Satisfies(o => o.Customer.Id == 1, "Customer should match")
.Satisfies(o => o.Items.Count > 0, "Should have items")
.Satisfies(o => o.Total > 0, "Total should be positive")
.Satisfies(o => o.Status == OrderStatus.Pending,
"New order should be pending");
}
Combine Assertive with complex testing scenarios including exception handling and edge cases.
[Fact]
public async Task ProcessPayment_ShouldHandleValidTransaction()
{
// Arrange
var payment = new Payment
{
Amount = 99.99m,
Currency = "USD",
Method = PaymentMethod.CreditCard
};
// Act
var result = await paymentService.ProcessAsync(payment);
// Assert - Complex validation chain
result.Assert()
.WithContext("Payment processing result")
.IsNotNull()
.Satisfies(r => r.IsSuccess, "Payment should succeed")
.Satisfies(r => !string.IsNullOrEmpty(r.TransactionId),
"Should have transaction ID")
.Satisfies(r => r.ProcessedAt <= DateTime.UtcNow,
"Processing time should be valid")
.Fails(r => r.HasErrors, "Should not have errors");
}
Noundry.Assertive works seamlessly with all popular .NET testing frameworks.
Perfect integration with xUnit.net for modern .NET testing with theories and parameterized tests.
using Noundry.Assertive;
using Xunit;
public class CalculatorTests
{
[Fact]
public void Add_TwoNumbers_ShouldReturnSum()
{
var result = new Calculator().Add(2, 3);
result.Assert().IsEqualTo(5);
}
[Theory]
[InlineData(1, 2, 3)]
[InlineData(10, 15, 25)]
public void Add_ParameterizedTest(int a, int b, int expected)
{
var result = new Calculator().Add(a, b);
result.Assert()
.IsEqualTo(expected)
.Satisfies(r => r >= a && r >= b);
}
}
Seamless integration with NUnit testing framework for comprehensive test suites.
using Noundry.Assertive;
using NUnit.Framework;
[TestFixture]
public class StringHelperTests
{
[Test]
public void FormatName_ShouldCapitalize()
{
var result = StringHelper.FormatName("john doe");
result.Assert()
.IsNotNull()
.IsEqualTo("John Doe");
}
[TestCase("", ExpectedResult = true)]
[TestCase(null, ExpectedResult = true)]
[TestCase("test", ExpectedResult = false)]
public bool IsNullOrEmpty_TestCases(string input)
{
var result = string.IsNullOrEmpty(input);
// Can be used in expression context
return result.Assert().IsOfType<bool>().Value;
}
}
Full support for Microsoft's MSTest framework with data-driven testing capabilities.
using Noundry.Assertive;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class DataServiceTests
{
[TestMethod]
public void GetUser_WithValidId_ShouldReturnUser()
{
var user = dataService.GetUser(1);
user.Assert()
.IsNotNull()
.Satisfies(u => u.Id == 1);
}
[DataTestMethod]
[DataRow("test@example.com", true)]
[DataRow("invalid-email", false)]
public void ValidateEmail_TestCases(string email, bool expected)
{
var result = validator.IsValidEmail(email);
result.Assert().IsEqualTo(expected);
}
}
Works beautifully with NUnit's rich assertion framework and test case attributes.
using Noundry.Assertive;
using NUnit.Framework;
[TestFixture]
public class OrderServiceTests
{
[SetUp]
public void Setup()
{
_orderService = new OrderService();
}
[Test]
public void CreateOrder_ShouldGenerateOrderNumber()
{
var order = _orderService.CreateOrder();
order.OrderNumber.Assert()
.IsNotNull()
.Satisfies(on => on.StartsWith("ORD-"));
}
[TestCase(0, ExpectedResult = false)]
[TestCase(-1, ExpectedResult = false)]
[TestCase(1, ExpectedResult = true)]
public bool IsValidQuantity_TestCases(int quantity)
{
var result = _orderService.IsValidQuantity(quantity);
return result.Assert().IsOfType<bool>().Value;
}
}
Native integration with Microsoft's testing framework for enterprise and Visual Studio environments.
using Noundry.Assertive;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class BusinessLogicTests
{
[TestInitialize]
public void Initialize()
{
_businessService = new BusinessService();
}
[TestMethod]
public void CalculateTotal_ShouldIncludeTax()
{
var total = _businessService.CalculateTotal(100m, 0.08m);
total.Assert()
.WithContext("Tax calculation")
.IsEqualTo(108m)
.IsInRange(100m, 200m);
}
[DataTestMethod]
[DataRow(100, 0.05, 105)]
[DataRow(200, 0.10, 220)]
public void TaxCalculation_DataDriven(decimal amount, decimal rate, decimal expected)
{
var result = _businessService.CalculateTotal(amount, rate);
result.Assert().IsEqualTo(expected);
}
}
Understanding how Assertive handles errors and following best practices for optimal testing.
Assertive throws AssertionException
when assertions fail, providing clear debugging information.
Detailed descriptions of what went wrong
Properties showing expected and actual values
Optional context for complex validation scenarios
try
{
42.Assert()
.WithContext("Age validation")
.IsEqualTo(18);
}
catch (AssertionException ex)
{
// ex.Message: "Age validation failed..."
// ex.Expected: 18
// ex.Actual: 42
}
Provide clear context in Satisfies and Fails methods
Order assertions from general to specific
Use WithContext for better error diagnostics
Works with any .NET testing framework
Start using Noundry.Assertive today and transform your test code into readable, expressive specifications.