GrpcAssertions 0.1.0
dotnet add package GrpcAssertions --version 0.1.0
NuGet\Install-Package GrpcAssertions -Version 0.1.0
<PackageReference Include="GrpcAssertions" Version="0.1.0" />
<PackageVersion Include="GrpcAssertions" Version="0.1.0" />
<PackageReference Include="GrpcAssertions" />
paket add GrpcAssertions --version 0.1.0
#r "nuget: GrpcAssertions, 0.1.0"
#:package GrpcAssertions@0.1.0
#addin nuget:?package=GrpcAssertions&version=0.1.0
#tool nuget:?package=GrpcAssertions&version=0.1.0
GrpcAssertions
Scope: Test projects only. Not intended for production code.
Framework-agnostic core for the GrpcAssertions package family. The TUnit-native fluent assertion entry points ship in the adapter package GrpcAssertions.TUnit.
Most users want
GrpcAssertions.TUnit, not this package directly. Install this core directly only when authoring a non-TUnit adapter or when you only need the test-double builder and predicates.
What's in this package
GrpcCallBuilder: buildsAsyncUnaryCall<T>instances for gRPC client test doubles, replacing the five-parameter constructor every hand-rolled fake repeats.Success<T>(T),Faulted<T>(RpcException),Faulted<T>(StatusCode, string?).GrpcOutcomeRendering: renders a gRPC outcome (StatusCodeplus truncatedStatus.Detail) for failure messages, shared so consumer-authored gRPC assertions produce identical diagnostics.GrpcExceptions:IsRpcException(Exception?)reports whether an exception is a gRPCRpcException(null and non-RpcExceptiontypes returnfalse).
All over the single Grpc.Core.Api dependency (RpcException / StatusCode / Status).
Install
dotnet add package GrpcAssertions.TUnit
The core (GrpcAssertions) comes transitively; install it directly only when authoring a non-TUnit adapter for the assertion family.
License
MIT throughout. Takes a single runtime dependency on Grpc.Core.Api (Apache-2.0), the package that defines the gRPC RpcException / StatusCode / Status types the assertions are about.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- Grpc.Core.Api (>= 2.80.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on GrpcAssertions:
| Package | Downloads |
|---|---|
|
GrpcAssertions.TUnit
TUnit-native gRPC assertions for .NET tests. Fluent ThrowsGrpcException / DoesNotThrowGrpcException on a delegate, with StatusCode shorthands (IsUnavailable, IsNotFound, and the rest) and WithDetail / WithDetailContaining refinements, plus the IsRpcException discriminator and the GrpcCallBuilder test-double helper from the framework-agnostic core. AOT-compatible, trimmable, no runtime reflection in the assertion path. |
GitHub repositories
This package is not used by any popular GitHub repositories.
View the rendered release notes: https://github.com/JohnVerheij/GrpcAssertions.TUnit/releases/tag/v0.1.0
Feature release. Lifts the package from skeleton to functional: the gRPC outcome-assertion surface ships. `ThrowsGrpcException()` asserts a delegate threw an `RpcException`, with `StatusCode` shorthands and `Status.Detail` refinements; `DoesNotThrowGrpcException()` covers the benign-error swallow tests; and `GrpcCallBuilder` removes the five-parameter `AsyncUnaryCall<T>` constructor that every hand-rolled gRPC fake repeats. The v0.0.1 `IsRpcException()` discriminator is preserved unchanged.
### Added
- **`Assert.That(() => call).ThrowsGrpcException()`** asserts the delegate throws a gRPC `RpcException` of any status; **`ThrowsGrpcException(StatusCode expected)`** asserts the status. Both return a `GrpcExceptionAssertion` chain, and failure messages render the actual `StatusCode` and `Status.Detail`. The entry points extend the delegate assertion source produced by `Assert.That(() => client.Method(...))`.
- **14 `StatusCode` shorthands** chaining off `ThrowsGrpcException()`: `IsOk`, `IsCancelled`, `IsInvalidArgument`, `IsDeadlineExceeded`, `IsNotFound`, `IsAlreadyExists`, `IsPermissionDenied`, `IsResourceExhausted`, `IsFailedPrecondition`, `IsAborted`, `IsUnimplemented`, `IsInternal`, `IsUnavailable`, `IsUnauthenticated`.
- **`WithDetail(string)`** (exact, ordinal) and **`WithDetailContaining(string, StringComparison)`** (substring, explicit comparison per the family convention) refine the assertion on `Status.Detail`.
- **`Assert.That(() => call).DoesNotThrowGrpcException()`** asserts the delegate completes without throwing an `RpcException`. A thrown `RpcException` fails with the gRPC outcome rendered; any other thrown exception fails naming its type and message.
- **`GrpcCallBuilder`** (core `GrpcAssertions` package): `Success<T>(T)`, `Faulted<T>(RpcException)`, and `Faulted<T>(StatusCode, string?)` build `AsyncUnaryCall<T>` instances for gRPC client test doubles, replacing the repeated five-parameter constructor. Both builders guard their arguments with `ArgumentNullException.ThrowIfNull`, a strict improvement over the hand-rolled fakes that would dereference-null later.
- **`GrpcOutcomeRendering`** (core): `Describe(RpcException)` and `DescribeStatus(StatusCode, string?)` render the status and detail (truncated at `MaxDetailLength`, 200 characters, with a horizontal-ellipsis suffix) for failure messages, shared so consumer-authored gRPC assertions produce identical diagnostics.
### Changed
- Pinned `PackageValidationBaselineVersion` to `0.0.1` on both packages; ApiCompat strict-mode now validates v0.1.0 against the v0.0.1 baseline at pack time. The v0.1.0 additions are purely additive (no breaking changes); strict-mode records the new public types as additive baseline suppressions (`CP0001`) in `CompatibilitySuppressions.xml`.
- Exempted `VSTHRD003` in test projects (`.editorconfig`). Tests routinely await Tasks created elsewhere (for example `AsyncUnaryCall<T>.ResponseAsync` from `GrpcCallBuilder`), which is safe under the no-`SynchronizationContext` test runner; the analyzer guards against a UI-thread deadlock that cannot occur here.