Dosaic.Testing.NUnit 1.2.8

There is a newer version of this package available.
See the version list below for details.
dotnet add package Dosaic.Testing.NUnit --version 1.2.8
                    
NuGet\Install-Package Dosaic.Testing.NUnit -Version 1.2.8
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Dosaic.Testing.NUnit" Version="1.2.8" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Dosaic.Testing.NUnit" Version="1.2.8" />
                    
Directory.Packages.props
<PackageReference Include="Dosaic.Testing.NUnit" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Dosaic.Testing.NUnit --version 1.2.8
                    
#r "nuget: Dosaic.Testing.NUnit, 1.2.8"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Dosaic.Testing.NUnit@1.2.8
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Dosaic.Testing.NUnit&version=1.2.8
                    
Install as a Cake Addin
#tool nuget:?package=Dosaic.Testing.NUnit&version=1.2.8
                    
Install as a Cake Tool

Dosaic.Testing.NUnit

A batteries-included meta-package for testing Dosaic-based services. Instead of tracking down individual testing dependencies for every project, add this single package and get a complete, pre-configured testing setup.

Installation

dotnet add package Dosaic.Testing.NUnit

Included Packages

Package Version Purpose
NUnit 4.5.0 Test framework
Allure.NUnit 2.14.1 Test reporting and attachments
AwesomeAssertions 9.4.0 Fluent assertion library (.Should())
NSubstitute 5.3.0 Mocking framework
NSubstitute.Analyzers.CSharp 1.0.17 Static analysis for correct NSubstitute usage (analyzer only)
Bogus 35.6.5 Fake data generation
NaughtyStrings.Bogus 3.0.0 Naughty/edge-case strings provider for Bogus
OpenTelemetry 1.15.0 Distributed tracing and metrics primitives
Microsoft.EntityFrameworkCore EF Core (required for EF assertion helpers)
Microsoft.EntityFrameworkCore.Relational EF Core relational (required for migration assertions)
Chronos.Net 2.0.24 Date/time provider abstractions
TngTech.ArchUnitNET.NUnit 0.13.2 Architecture unit tests

The package also carries transitive project references to Dosaic.Hosting.Abstractions (core plugin interfaces) and Dosaic.DevTools.Seeding (EF Core fake data seeder).

Test Helpers

Type Namespace Description
FakeLogger<T> Dosaic.Testing.NUnit.Assertions In-memory ILogger<T> that captures log entries for assertion
TestMetricsCollector Dosaic.Testing.NUnit Listens to a named System.Diagnostics.Metrics instrument and collects measurements
TestMetricsCollectorAssertions Dosaic.Testing.NUnit Fluent assertion extensions for List<MetricMeasurement>
ActivityTestBootstrapper Dosaic.Testing.NUnit Registers a global ActivityListener so Activity instances are sampled in tests
TestingDefaults Dosaic.Testing.NUnit Creates a pre-configured ServiceCollection / ServiceProvider with logging, date-time providers, and GlobalStatusCodeOptions
CustomConfiguration Dosaic.Testing.NUnit Fluent builder for in-memory IConfiguration instances
BaseTestEntity / BaseSubTestEntity Dosaic.Testing.NUnit.Models Reusable record types for tests that need a simple entity graph
PluginServiceConfigurationAssertions Dosaic.Testing.NUnit.Assertions Asserts that an IPluginServiceConfiguration registers expected services
PluginEndpointConfigurationAssertions Dosaic.Testing.NUnit.Assertions Asserts that an IPluginEndpointsConfiguration registers expected routes and HTTP methods
EntityTypeAssertions / DbContextAssertions Dosaic.Testing.NUnit.Assertions Fluent assertions for EF Core entity type mappings, migrations, indexes, foreign keys, and seed data
TracingAssertions Dosaic.Testing.NUnit.Assertions Asserts that a TracerProvider has registered expected activity sources and instrumentations
ArgExt Dosaic.Testing.NUnit.Extensions NSubstitute argument matcher that delegates matching to an AwesomeAssertions assertion action
ArchitectureExtensions Dosaic.Testing.NUnit.Extensions Helpers for loading Architecture instances from the current or specific assemblies (ArchUnitNET)
ObjectExtensions Dosaic.Testing.NUnit.Extensions Reflection helper to read private/internal fields or properties by name

Usage

FakeLogger<T>

Capture and assert on log entries without a real logging infrastructure.

using Dosaic.Testing.NUnit.Assertions;
using Microsoft.Extensions.Logging;

var logger = new FakeLogger<MyService>();
var service = new MyService(logger);

service.DoSomething();

logger.Entries.Should().ContainSingle(e =>
    e.Level == LogLevel.Information &&
    e.Message.Contains("expected message"));

TestMetricsCollector

Listen to a named System.Diagnostics.Metrics instrument and verify emitted measurements.

using Dosaic.Testing.NUnit;

using var metricsCollector = new TestMetricsCollector("my-metric-name");
metricsCollector.CollectedMetrics.Should().BeEmpty();

// exercise the code under test
await service.ProcessAsync();

metricsCollector.Instruments.Should().Contain("my-metric-name");

// assert a measurement with value 1
metricsCollector.CollectedMetrics.Should().ContainsMetric(1);

// assert with a specific tag
metricsCollector.CollectedMetrics.Should().ContainsMetric(1, "status", "ok");

// assert with multiple tags
metricsCollector.CollectedMetrics.Should().ContainsMetric(
    1,
    new[] { new KeyValuePair<string, string>("status", "ok") });

// sum all measurements (useful for gauges triggered via RecordObservableInstruments)
metricsCollector.RecordObservableInstruments();
metricsCollector.GetSum().Should().Be(42);

ActivityTestBootstrapper

Enable Activity recording in tests (call once, e.g. in [OneTimeSetUp]).

using Dosaic.Testing.NUnit;
using NUnit.Framework;

[SetUpFixture]
public class TestBootstrap
{
    [OneTimeSetUp]
    public void Setup() => ActivityTestBootstrapper.Setup();
}

TestingDefaults

Get a pre-wired ServiceCollection or ServiceProvider including logging and Chronos date-time providers.

using Dosaic.Testing.NUnit;

// obtain a ServiceProvider with defaults
var sp = TestingDefaults.ServiceProvider();

// or start from the collection and register additional services
var sc = TestingDefaults.ServiceCollection();
sc.AddSingleton<IMyService, MyService>();
var provider = sc.BuildServiceProvider();

CustomConfiguration

Build an IConfiguration from key/value pairs without touching the file system.

using Dosaic.Testing.NUnit;

var config = CustomConfiguration.Create()
    .Add("Database:Host", "localhost")
    .Add("Database:Port", "5432")
    .Build();

// use the empty singleton where no config values are needed
IConfiguration empty = CustomConfiguration.Empty;

PluginServiceConfigurationAssertions

Verify that a plugin registers the expected services into the DI container.

using Dosaic.Testing.NUnit.Assertions;

var plugin = new MyPlugin(/* dependencies */);

plugin.ShouldHaveServices(new Dictionary<Type, Type>
{
    { typeof(IMyService), typeof(MyService) },
    { typeof(IMyRepository), null }, // null = only check that it is registered
});

PluginEndpointConfigurationAssertions

Verify that a plugin registers the expected routes and HTTP methods.

using System.Net.Http;
using Dosaic.Testing.NUnit.Assertions;

var plugin = new MyEndpointsPlugin(/* dependencies */);

plugin.ShouldHaveEndpoints(new Dictionary<string, HttpMethod[]>
{
    { "/api/items", new[] { HttpMethod.Get, HttpMethod.Post } },
    { "/api/items/{id}", new[] { HttpMethod.Get, HttpMethod.Put, HttpMethod.Delete } },
});

// retrieve a single endpoint for further assertions
var endpoint = plugin.GetEndpoint(HttpMethod.Get, "/api/items");
endpoint.Should().NotBeNull();

EF Core Assertions (EntityTypeAssertions / DbContextAssertions)

Assert EF Core entity mappings, migration state, and seed data.

using AwesomeAssertions;
using Dosaic.Testing.NUnit.Assertions;

// entity type mapping assertions
var entityType = dbContext.Model.FindEntityType(typeof(Customer))!;

entityType.Should().BeOnTable("public", "customers");
entityType.Should().HavePrimaryKey<Guid>("Id");
entityType.Should().HaveProperty<string>("Name", isNullable: false, maxLength: 200);
entityType.Should().HaveProperty<int>("Age");
entityType.Should().HaveIndex("Email", isUnique: true);
entityType.Should().HaveForeignKey("OrderId", typeof(Order));
entityType.Should().HasCheckConstraint("chk_age", "age > 0");
entityType.Should().HaveData(new[] { new Customer { Id = Guid.Parse("..."), Name = "Seed" } });

// migration assertions (no pending model changes)
dbContext.Should().MatchMigrations<MyDbContext>();

// compiled model assertion
dbContext.Should().MatchCompiledModel(MyCompiledModel.Instance);

TracingAssertions

Verify that a TracerProvider (built during plugin configuration) has registered the correct sources and instrumentations.

using Dosaic.Testing.NUnit.Assertions;

var sc = TestingDefaults.ServiceCollection();
// configure plugin which adds OpenTelemetry tracing
plugin.ConfigureServices(sc);
var sp = sc.BuildServiceProvider();

sp.Should().RegisterSources("MyService.ActivitySource");
sp.Should().RegisterSources(new[] { "Source1", "Source2" });
sp.Should().RegisterInstrumentation<HttpClientInstrumentation>();
sp.Should().RegisterInstrumentation("AspNetCoreInstrumentation");

ArgExt (NSubstitute argument matching with AwesomeAssertions)

Use fluent assertion lambdas as NSubstitute argument matchers.

using Dosaic.Testing.NUnit.Extensions;
using NSubstitute;

var repository = Substitute.For<IOrderRepository>();

await service.PlaceOrderAsync(new Order { CustomerId = 42, Total = 99.99m });

await repository.Received(1).SaveAsync(
    ArgExt.Is<Order>(order =>
    {
        order.CustomerId.Should().Be(42);
        order.Total.Should().Be(99.99m);
    }));

ArchitectureExtensions

Load an Architecture from the calling assembly or a set of specific assemblies for use with ArchUnitNET.

using ArchUnitNET.Fluent;
using ArchUnitNET.Loader;
using Dosaic.Testing.NUnit.Extensions;
using NUnit.Framework;

[TestFixture]
public class ArchitectureTests
{
    private static readonly Architecture _architecture =
        new ArchLoader().FromCurrentAssembly();

    [Test]
    public void ServicesShouldNotDependOnControllers()
    {
        var services = ArchRuleDefinition.Classes()
            .That().ResideInNamespace("MyApp.Services");

        var controllers = ArchRuleDefinition.Classes()
            .That().ResideInNamespace("MyApp.Controllers");

        services.Should().NotDependOnAny(controllers).Check(_architecture);
    }
}

ObjectExtensions

Read private or internal fields and properties by name via reflection (useful when testing internal state without exposing it).

using Dosaic.Testing.NUnit.Extensions;

var service = new MyService();
// access a private field named "_cache"
var cache = service.GetInaccessibleValue<Dictionary<string, object>>("_cache");
cache.Should().BeEmpty();
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.9 0 3/13/2026
1.2.8 81 3/9/2026
1.2.7 81 3/4/2026
1.2.6 91 2/19/2026
1.2.5 94 2/17/2026
1.2.4 111 2/13/2026
1.2.3 111 1/27/2026
1.2.2 306 12/16/2025
1.2.1 276 12/16/2025
1.2.0 436 12/11/2025
1.1.21 455 12/10/2025
1.1.20 435 11/18/2025
1.1.19 318 11/11/2025
1.1.18 210 10/14/2025
1.1.17 209 10/1/2025
1.1.16 217 9/25/2025
1.1.15 217 9/24/2025
1.1.14 219 9/24/2025
1.1.13 214 9/24/2025
1.1.12 333 9/16/2025
Loading failed