Spensara Spensara Knowledge Base & Documentation Repository

Repository Docs & Knowledge Base

Consolidated Spensara documentation repository (722 Markdown & architecture documents in ../repository)
Built Word Documents (.docx): Spensara Overview (.docx) Capability Assessment (.docx) Brink POS Ingestion Analysis (.docx) The Borg Ingestion Architecture (.docx)

Agent Tooling (71)

Automation workflows, orchestration references, and developer tooling guides.
agent-tooling/.agents/skills/tunit-testing/references/assertions.md 10,224 bytes · Updated Oct 23, 2026 10:44 AM EDT
Raw File

Assertions Reference

Complete reference for TUnit assertions.

Table of Contents

Core Principles

All assertions:

  • Use Assert.That(value) syntax
  • Must be awaited to execute
  • Return fluent builder objects for chaining
  • Provide clear error messages on failure
csharp
// Always await assertions
await Assert.That(actual).IsEqualTo(expected);

// Chaining
await Assert.That(value)
    .IsNotNull()
    .And.IsGreaterThan(0);

Equality & Comparison

Equality

csharp
await Assert.That(actual).IsEqualTo(expected);
await Assert.That(actual).IsNotEqualTo(other);
await Assert.That(actual).IsSameReference(expected);
await Assert.That(actual).IsNotSameReference(other);

Comparison

csharp
await Assert.That(value).IsGreaterThan(10);
await Assert.That(value).IsGreaterThanOrEqualTo(10);
await Assert.That(value).IsLessThan(100);
await Assert.That(value).IsLessThanOrEqualTo(100);
await Assert.That(value).IsBetween(10, 100);  // Inclusive

With Tolerance

For floating-point comparisons:

csharp
await Assert.That(3.14159).IsEqualTo(Math.PI).Within(0.001);
await Assert.That(actual).IsCloseTo(expected, tolerance: 0.01);

Null & Default

csharp
await Assert.That(value).IsNull();
await Assert.That(value).IsNotNull();
await Assert.That(value).IsDefault();      // default(T)
await Assert.That(value).IsNotDefault();

Boolean

csharp
await Assert.That(condition).IsTrue();
await Assert.That(condition).IsFalse();

Numeric

All comparison assertions work with numeric types:

csharp
await Assert.That(42).IsPositive();
await Assert.That(-10).IsNegative();
await Assert.That(0).IsZero();
await Assert.That(5).IsOdd();
await Assert.That(4).IsEven();

String

Content

csharp
await Assert.That(str).IsEmpty();
await Assert.That(str).IsNotEmpty();
await Assert.That(str).Contains("substring");
await Assert.That(str).DoesNotContain("substring");
await Assert.That(str).StartsWith("prefix");
await Assert.That(str).EndsWith("suffix");

Pattern Matching

csharp
await Assert.That(email).Matches(@"^[\w\.-]+@[\w\.-]+\.\w+$");
await Assert.That(text).DoesNotMatch(@"\d+");  // No digits

Length

csharp
await Assert.That(str).Length().IsEqualTo(10);
await Assert.That(str).Length().IsGreaterThan(5);

Case Sensitivity

csharp
// Case-insensitive comparison
await Assert.That("Hello").IsEqualTo("hello", StringComparison.OrdinalIgnoreCase);

Collections

Basic Checks

csharp
await Assert.That(collection).IsEmpty();
await Assert.That(collection).IsNotEmpty();
await Assert.That(collection).Count().IsEqualTo(5);
await Assert.That(collection).Count().IsGreaterThan(0);

Membership

csharp
await Assert.That(collection).Contains(item);
await Assert.That(collection).DoesNotContain(item);
await Assert.That(collection).ContainsAll(item1, item2, item3);
await Assert.That(collection).ContainsAny(item1, item2);

Predicates

csharp
await Assert.That(numbers).All(n => n > 0);
await Assert.That(numbers).Any(n => n == 42);
await Assert.That(numbers).None(n => n < 0);

Single Item

csharp
// Returns the single item if count == 1
var item = await Assert.That(collection).HasSingleItem();
await Assert.That(item.Name).IsEqualTo("Expected");

Contains with Predicate

csharp
// Returns the found item
var admin = await Assert.That(users).Contains(u => u.Role == "Admin");
await Assert.That(admin.Permissions).IsNotEmpty();

Ordering

csharp
await Assert.That(numbers).IsInOrder();
await Assert.That(numbers).IsInDescendingOrder();

Equivalence

csharp
// Same items, any order
await Assert.That(actual).IsEquivalentTo(expected);

// Exact order required
await Assert.That(actual).IsEqualTo(expected);

Arrays And Buffers

For byte[] and similar payload buffers, prefer IsEquivalentTo(...) when you mean element-by-element equality of contents.

csharp
await Assert.That(actualBytes).IsEquivalentTo(expectedBytes);

If a failure says the contents are the same but the reference is different, you likely want equivalence rather than direct equality.

HTTP Responses

TUnit provides built-in HTTP response assertions:

Specific Status Codes

csharp
await Assert.That(response).IsOk();               // 200
await Assert.That(response).IsCreated();          // 201
await Assert.That(response).IsNoContent();        // 204
await Assert.That(response).IsBadRequest();       // 400
await Assert.That(response).IsUnauthorized();     // 401
await Assert.That(response).IsForbidden();        // 403
await Assert.That(response).IsNotFound();         // 404
await Assert.That(response).IsConflict();         // 409

Parameterized

csharp
await Assert.That(response).HasStatusCode(HttpStatusCode.Created);
await Assert.That(response).HasStatusCode(HttpStatusCode.Accepted);

Range Checks

csharp
await Assert.That(response).IsSuccessStatusCode();       // 200-299
await Assert.That(response).IsRedirectStatusCode();      // 300-399
await Assert.That(response).IsClientErrorStatusCode();   // 400-499
await Assert.That(response).IsServerErrorStatusCode();   // 500-599

Content & Headers

csharp
await Assert.That(response).HasJsonContent();
await Assert.That(response).HasContentType("application/json");
await Assert.That(response).HasHeader("X-Request-Id");
await Assert.That(response).HasHeader("Content-Type", "application/json");

Complete Example

csharp
var response = await client.PostAsJsonAsync("/alerts", request);

await Assert.That(response).IsCreated();
await Assert.That(response).HasJsonContent();
await Assert.That(response).HasHeader("Location");

var alert = await response.Content.ReadFromJsonAsync<AlertResponse>();
await Assert.That(alert).IsNotNull();
await Assert.That(alert.Name).IsEqualTo(request.Name);

Exceptions

Basic Exception Testing

csharp
await Assert.That(() => DivideByZero())
    .Throws<DivideByZeroException>();

await Assert.That(async () => await service.ProcessAsync())
    .Throws<InvalidOperationException>();

With Message Validation

csharp
await Assert.That(() => ThrowException())
    .Throws<ArgumentException>()
    .WithMessage("Parameter name: value");

await Assert.That(() => ThrowException())
    .Throws<ArgumentException>()
    .WithMessageContaining("value");

No Exception

csharp
await Assert.That(() => SafeOperation()).ThrowsNothing();
await Assert.That(async () => await SafeAsync()).ThrowsNothing();

Type Assertions

csharp
await Assert.That(obj).IsTypeOf<MyClass>();
await Assert.That(obj).IsNotTypeOf<OtherClass>();
await Assert.That(typeof(Dog)).IsAssignableTo<Animal>();
await Assert.That(typeof(Dog)).IsAssignableFrom<Animal>();

Chaining & Composition

And Conditions

Chain assertions on the same value:

csharp
await Assert.That(username)
    .IsNotNull()
    .And.IsNotEmpty()
    .And.Length().IsGreaterThan(3)
    .And.Length().IsLessThan(20);

Or Conditions

Any condition can be true:

csharp
await Assert.That(statusCode)
    .IsEqualTo(200)
    .Or.IsEqualTo(201)
    .Or.IsEqualTo(204);

Member Assertions

Assert on object properties:

csharp
await Assert.That(person)
    .Member(p => p.Name, name => name.IsEqualTo("Alice"))
    .And.Member(p => p.Age, age => age.IsGreaterThan(18));

// Nested properties
await Assert.That(order)
    .Member(o => o.Customer.Address.City, city => city.IsEqualTo("Seattle"));

Assert.Multiple

Group related assertions to see all failures:

csharp
using (Assert.Multiple())
{
    await Assert.That(user.FirstName).IsEqualTo("John");
    await Assert.That(user.LastName).IsEqualTo("Doe");
    await Assert.That(user.Age).IsGreaterThan(18);
    await Assert.That(user.Email).IsNotNull();
}
// All failures reported together

Custom Expectations

csharp
// Simple predicate
await Assert.That(value).Satisfies(v => v % 2 == 0, "Value must be even");

// Map and assert
await Assert.That(order)
    .Satisfies(o => o.Total, total => total > 100);

Common Patterns

Testing Validation Results

csharp
var result = validator.Validate(input);

using (Assert.Multiple())
{
    await Assert.That(result.IsValid).IsFalse();
    await Assert.That(result.Errors).Count().IsEqualTo(2);
    await Assert.That(result.Errors).Any(e => e.PropertyName == "Email");
}

Testing API Responses

csharp
var response = await client.GetAsync("/users/123");

await Assert.That(response).IsOk();
await Assert.That(response).HasJsonContent();

var user = await response.Content.ReadFromJsonAsync<User>();

using (Assert.Multiple())
{
    await Assert.That(user).IsNotNull();
    await Assert.That(user.Id).IsEqualTo(123);
    await Assert.That(user.Name).IsNotEmpty();
    await Assert.That(user.Email).Matches(@"^[\w\.-]+@[\w\.-]+\.\w+$");
}

Testing Collections with Conditions

csharp
var activeUsers = await repository.GetActiveUsersAsync();

await Assert.That(activeUsers).IsNotEmpty();
await Assert.That(activeUsers).All(u => u.IsActive);
await Assert.That(activeUsers).Any(u => u.Role == "Admin");

var admin = await Assert.That(activeUsers).Contains(u => u.Role == "Admin");
await Assert.That(admin.Permissions).ContainsAll("Read", "Write", "Delete");

Best Practices

  1. Use specific assertions - IsOk() instead of HasStatusCode(HttpStatusCode.OK)
  2. Chain related assertions - Use .And for multiple checks on same value
  3. Group with Assert.Multiple - See all failures at once
  4. Return values from assertions - Use HasSingleItem(), Contains(predicate) to continue asserting
  5. Always await - Assertions must be awaited to execute
  6. One logical assertion per test - Multiple technical assertions OK if testing same behavior