Skip to main content

Specialized Type Assertions

TUnit provides assertions for many specialized .NET types beyond the common primitives. This page covers GUID, HTTP, file system, networking, and other specialized assertions.

GUID Assertions​

IsEmptyGuid / IsNotEmptyGuid​

Tests whether a GUID is empty (Guid.Empty):

[Test]
public async Task GUID_Is_Empty()
{
var emptyGuid = Guid.Empty;
await Assert.That(emptyGuid).IsEmptyGuid();

var newGuid = Guid.NewGuid();
await Assert.That(newGuid).IsNotEmptyGuid();
}

Practical usage:

[Test]
public async Task Entity_Has_Valid_ID()
{
var entity = new Entity { Id = Guid.NewGuid() };

await Assert.That(entity.Id).IsNotEmptyGuid();
await Assert.That(entity.Id).IsNotEqualTo(Guid.Empty);
}

HTTP Status Code Assertions​

IsSuccess​

Tests for 2xx success status codes:

[Test]
public async Task HTTP_Success_Status()
{
var response = await _client.GetAsync("/api/users");

await Assert.That(response.StatusCode).IsSuccess();
}

Works with all 2xx codes:

[Test]
public async Task Various_Success_Codes()
{
await Assert.That(HttpStatusCode.OK).IsSuccess(); // 200
await Assert.That(HttpStatusCode.Created).IsSuccess(); // 201
await Assert.That(HttpStatusCode.Accepted).IsSuccess(); // 202
await Assert.That(HttpStatusCode.NoContent).IsSuccess(); // 204
}

IsNotSuccess​

[Test]
public async Task HTTP_Not_Success()
{
await Assert.That(HttpStatusCode.NotFound).IsNotSuccess(); // 404
await Assert.That(HttpStatusCode.InternalServerError).IsNotSuccess(); // 500
}

IsClientError​

Tests for 4xx client error status codes:

[Test]
public async Task HTTP_Client_Error()
{
await Assert.That(HttpStatusCode.BadRequest).IsClientError(); // 400
await Assert.That(HttpStatusCode.Unauthorized).IsClientError(); // 401
await Assert.That(HttpStatusCode.Forbidden).IsClientError(); // 403
await Assert.That(HttpStatusCode.NotFound).IsClientError(); // 404
}

IsServerError​

Tests for 5xx server error status codes:

[Test]
public async Task HTTP_Server_Error()
{
await Assert.That(HttpStatusCode.InternalServerError).IsServerError(); // 500
await Assert.That(HttpStatusCode.BadGateway).IsServerError(); // 502
await Assert.That(HttpStatusCode.ServiceUnavailable).IsServerError(); // 503
}

IsRedirection​

Tests for 3xx redirection status codes:

[Test]
public async Task HTTP_Redirection()
{
await Assert.That(HttpStatusCode.MovedPermanently).IsRedirection(); // 301
await Assert.That(HttpStatusCode.Found).IsRedirection(); // 302
await Assert.That(HttpStatusCode.TemporaryRedirect).IsRedirection(); // 307
}

CancellationToken Assertions​

IsCancellationRequested / IsNotCancellationRequested​

[Test]
public async Task CancellationToken_Is_Requested()
{
var cts = new CancellationTokenSource();
cts.Cancel();

await Assert.That(cts.Token).IsCancellationRequested();
}

[Test]
public async Task CancellationToken_Not_Requested()
{
var cts = new CancellationTokenSource();

await Assert.That(cts.Token).IsNotCancellationRequested();
}

CanBeCanceled / CannotBeCanceled​

[Test]
public async Task Token_Can_Be_Canceled()
{
var cts = new CancellationTokenSource();

await Assert.That(cts.Token).CanBeCanceled();
}

[Test]
public async Task Default_Token_Cannot_Be_Canceled()
{
var token = CancellationToken.None;

await Assert.That(token).CannotBeCanceled();
}

Character Assertions​

IsLetter / IsNotLetter​

[Test]
public async Task Char_Is_Letter()
{
await Assert.That('A').IsLetter();
await Assert.That('z').IsLetter();

await Assert.That('5').IsNotLetter();
await Assert.That('!').IsNotLetter();
}

IsDigit / IsNotDigit​

[Test]
public async Task Char_Is_Digit()
{
await Assert.That('0').IsDigit();
await Assert.That('9').IsDigit();

await Assert.That('A').IsNotDigit();
}

IsWhiteSpace / IsNotWhiteSpace​

[Test]
public async Task Char_Is_WhiteSpace()
{
await Assert.That(' ').IsWhiteSpace();
await Assert.That('\t').IsWhiteSpace();
await Assert.That('\n').IsWhiteSpace();

await Assert.That('A').IsNotWhiteSpace();
}

IsUpper / IsNotUpper​

[Test]
public async Task Char_Is_Upper()
{
await Assert.That('A').IsUpper();
await Assert.That('Z').IsUpper();

await Assert.That('a').IsNotUpper();
}

IsLower / IsNotLower​

[Test]
public async Task Char_Is_Lower()
{
await Assert.That('a').IsLower();
await Assert.That('z').IsLower();

await Assert.That('A').IsNotLower();
}

IsPunctuation / IsNotPunctuation​

[Test]
public async Task Char_Is_Punctuation()
{
await Assert.That('.').IsPunctuation();
await Assert.That(',').IsPunctuation();
await Assert.That('!').IsPunctuation();

await Assert.That('A').IsNotPunctuation();
}

File System Assertions​

DirectoryInfo​

Exists / DoesNotExist​

[Test]
public async Task Directory_Exists()
{
var tempDir = new DirectoryInfo(Path.GetTempPath());

await Assert.That(tempDir).Exists();
}

[Test]
public async Task Directory_Does_Not_Exist()
{
var nonExistent = new DirectoryInfo(@"C:\NonExistentFolder");

await Assert.That(nonExistent).DoesNotExist();
}

HasFiles / IsEmpty​

[Test]
public async Task Directory_Has_Files()
{
var tempDir = new DirectoryInfo(Path.GetTempPath());

// Likely has files
await Assert.That(tempDir).HasFiles();
}

[Test]
public async Task Directory_Is_Empty()
{
var emptyDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()));

await Assert.That(emptyDir).IsEmpty();

// Cleanup
emptyDir.Delete();
}

HasSubdirectories / HasNoSubdirectories​

[Test]
public async Task Directory_Has_Subdirectories()
{
var windowsDir = new DirectoryInfo(@"C:\Windows");

await Assert.That(windowsDir).HasSubdirectories();
}

FileInfo​

Exists / DoesNotExist​

[Test]
public async Task File_Exists()
{
var tempFile = Path.GetTempFileName();
var fileInfo = new FileInfo(tempFile);

await Assert.That(fileInfo).Exists();

// Cleanup
File.Delete(tempFile);
}

[Test]
public async Task File_Does_Not_Exist()
{
var nonExistent = new FileInfo(@"C:\nonexistent.txt");

await Assert.That(nonExistent).DoesNotExist();
}

IsReadOnly / IsNotReadOnly​

[Test]
public async Task File_Is_ReadOnly()
{
var tempFile = Path.GetTempFileName();
var fileInfo = new FileInfo(tempFile);

fileInfo.IsReadOnly = true;
await Assert.That(fileInfo).IsReadOnly();

fileInfo.IsReadOnly = false;
await Assert.That(fileInfo).IsNotReadOnly();

// Cleanup
File.Delete(tempFile);
}

IsHidden / IsNotHidden​

[Test]
public async Task File_Is_Hidden()
{
var tempFile = Path.GetTempFileName();
var fileInfo = new FileInfo(tempFile);

fileInfo.Attributes |= FileAttributes.Hidden;
await Assert.That(fileInfo).IsHidden();

// Cleanup
fileInfo.Attributes &= ~FileAttributes.Hidden;
File.Delete(tempFile);
}

IsSystem / IsNotSystem​

[Test]
public async Task File_Is_System()
{
// System files are typically in System32
var systemFile = new FileInfo(@"C:\Windows\System32\kernel32.dll");

if (systemFile.Exists)
{
await Assert.That(systemFile).IsSystem();
}
}

IsExecutable / IsNotExecutable​

[Test]
public async Task File_Is_Executable()
{
var exeFile = new FileInfo(@"C:\Windows\notepad.exe");

if (exeFile.Exists)
{
await Assert.That(exeFile).IsExecutable();
}
}

IP Address Assertions​

IsIPv4 / IsNotIPv4​

[Test]
public async Task IP_Is_IPv4()
{
var ipv4 = IPAddress.Parse("192.168.1.1");

await Assert.That(ipv4).IsIPv4();
}

[Test]
public async Task IP_Not_IPv4()
{
var ipv6 = IPAddress.Parse("::1");

await Assert.That(ipv6).IsNotIPv4();
}

IsIPv6 / IsNotIPv6​

[Test]
public async Task IP_Is_IPv6()
{
var ipv6 = IPAddress.Parse("2001:0db8:85a3:0000:0000:8a2e:0370:7334");

await Assert.That(ipv6).IsIPv6();
}

[Test]
public async Task IP_Not_IPv6()
{
var ipv4 = IPAddress.Parse("127.0.0.1");

await Assert.That(ipv4).IsNotIPv6();
}

Lazy<T> Assertions​

IsValueCreated / IsNotValueCreated​

[Test]
public async Task Lazy_Value_Not_Created()
{
var lazy = new Lazy<int>(() => 42);

await Assert.That(lazy).IsNotValueCreated();

var value = lazy.Value;

await Assert.That(lazy).IsValueCreated();
await Assert.That(value).IsEqualTo(42);
}

Stream Assertions​

CanRead / CannotRead​

[Test]
public async Task Stream_Can_Read()
{
using var stream = new MemoryStream();

await Assert.That(stream).CanRead();
}

CanWrite / CannotWrite​

[Test]
public async Task Stream_Can_Write()
{
using var stream = new MemoryStream();

await Assert.That(stream).CanWrite();
}

[Test]
public async Task Stream_Cannot_Write()
{
var readOnlyStream = new MemoryStream(new byte[10], writable: false);

await Assert.That(readOnlyStream).CannotWrite();
}

CanSeek / CannotSeek​

[Test]
public async Task Stream_Can_Seek()
{
using var stream = new MemoryStream();

await Assert.That(stream).CanSeek();
}

CanTimeout / CannotTimeout​

[Test]
public async Task Network_Stream_Can_Timeout()
{
using var client = new TcpClient();
// Note: stream only available after connection
// await Assert.That(stream).CanTimeout();
}

Process Assertions​

HasExited / HasNotExited​

[Test]
public async Task Process_Has_Not_Exited()
{
var process = Process.Start("notepad.exe");

await Assert.That(process).HasNotExited();

process.Kill();
process.WaitForExit();

await Assert.That(process).HasExited();
}

IsResponding / IsNotResponding​

[Test]
public async Task Process_Is_Responding()
{
var process = Process.GetCurrentProcess();

await Assert.That(process).IsResponding();
}

Thread Assertions​

IsAlive / IsNotAlive​

[Test]
public async Task Thread_Is_Alive()
{
var thread = new Thread(() => Thread.Sleep(1000));
thread.Start();

await Assert.That(thread).IsAlive();

thread.Join();
await Assert.That(thread).IsNotAlive();
}

IsBackground / IsNotBackground​

[Test]
public async Task Thread_Is_Background()
{
var thread = new Thread(() => { });
thread.IsBackground = true;

await Assert.That(thread).IsBackground();
}

IsThreadPoolThread / IsNotThreadPoolThread​

[Test]
public async Task Check_ThreadPool_Thread()
{
var currentThread = Thread.CurrentThread;

// Test thread is typically not a thread pool thread
await Assert.That(currentThread).IsNotThreadPoolThread();
}

WeakReference Assertions​

IsAlive / IsNotAlive​

[Test]
public async Task WeakReference_Is_Alive()
{
var obj = new object();
var weakRef = new WeakReference(obj);

await Assert.That(weakRef).IsAlive();

obj = null!;
GC.Collect();
GC.WaitForPendingFinalizers();

await Assert.That(weakRef).IsNotAlive();
}

URI Assertions​

IsAbsoluteUri / IsNotAbsoluteUri​

[Test]
public async Task URI_Is_Absolute()
{
var absolute = new Uri("https://example.com/path");

await Assert.That(absolute).IsAbsoluteUri();
}

[Test]
public async Task URI_Is_Relative()
{
var relative = new Uri("/path/to/resource", UriKind.Relative);

await Assert.That(relative).IsNotAbsoluteUri();
}

Encoding Assertions​

IsUtf8 / IsNotUtf8​

[Test]
public async Task Encoding_Is_UTF8()
{
var encoding = Encoding.UTF8;

await Assert.That(encoding).IsUtf8();
}

[Test]
public async Task Encoding_Not_UTF8()
{
var encoding = Encoding.ASCII;

await Assert.That(encoding).IsNotUtf8();
}

Version Assertions​

Version comparisons using standard comparison operators:

[Test]
public async Task Version_Comparison()
{
var v1 = new Version(1, 0, 0);
var v2 = new Version(2, 0, 0);

await Assert.That(v2).IsGreaterThan(v1);
await Assert.That(v1).IsLessThan(v2);
}

DayOfWeek Assertions​

IsWeekend / IsNotWeekend​

[Test]
public async Task Day_Is_Weekend()
{
await Assert.That(DayOfWeek.Saturday).IsWeekend();
await Assert.That(DayOfWeek.Sunday).IsWeekend();
}

IsWeekday / IsNotWeekday​

[Test]
public async Task Day_Is_Weekday()
{
await Assert.That(DayOfWeek.Monday).IsWeekday();
await Assert.That(DayOfWeek.Tuesday).IsWeekday();
await Assert.That(DayOfWeek.Wednesday).IsWeekday();
await Assert.That(DayOfWeek.Thursday).IsWeekday();
await Assert.That(DayOfWeek.Friday).IsWeekday();
}

Practical Examples​

API Testing​

[Test]
public async Task API_Returns_Success()
{
var response = await _client.GetAsync("/api/health");

await Assert.That(response.StatusCode).IsSuccess();
await Assert.That(response.StatusCode).IsNotEqualTo(HttpStatusCode.InternalServerError);
}

File Upload Validation​

[Test]
public async Task Uploaded_File_Validation()
{
var uploadedFile = new FileInfo("upload.txt");

await Assert.That(uploadedFile).Exists();
await Assert.That(uploadedFile).IsNotReadOnly();
await Assert.That(uploadedFile.Length).IsGreaterThan(0);
}

Configuration Directory Check​

[Test]
public async Task Config_Directory_Setup()
{
var configDir = new DirectoryInfo(@"C:\ProgramData\MyApp");

await Assert.That(configDir).Exists();
await Assert.That(configDir).HasFiles();
}

Network Validation​

[Test]
public async Task Server_IP_Is_Valid()
{
var serverIp = IPAddress.Parse(Configuration["ServerIP"]);

await Assert.That(serverIp).IsIPv4();
}

See Also​

  • Boolean - For boolean properties of specialized types
  • String - For string conversions and properties
  • Collections - For collections of specialized types
  • Types - For type checking specialized types