Silky Microservice FrameworkSilky Microservice Framework
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
Home
Docs
Config
Source
github
gitee
  • 简体中文
  • English
  • Introduction

    • Silky Framework Overview
  • Getting Started

    • Glossary
    • Quick Start
    • Project Template
    • Microservice Architecture
    • Sample Projects
  • Host & Module

    • Host Types
    • Gateway Configuration
    • Module System
    • Plugin System
  • Gateway & HTTP

    • Swagger / OpenAPI
    • MiniProfiler
    • CORS
    • Audit Logging
  • Service & RPC

    • App Services & Service Entries
    • RPC Communication
    • WebSocket
    • Service Registry
    • Service Governance
  • Data & Cache

    • EFCore Data Access
    • Caching
    • Distributed Lock
  • Security & Auth

    • Identity & Authentication
    • Distributed Transactions
  • Infrastructure

    • Dependency Injection
    • Object Mapping
    • Validation
    • Link Tracking (SkyAPM)
    • Logging (Serilog)
    • Health Checks
    • Message Bus (MassTransit)
    • Unit & Integration Testing

Overview

Silky provides integration testing infrastructure through the Silky.TestBase module. Unlike pure unit tests, integration tests start a real Autofac IoC container, load module dependencies, and execute code in a context close to the real runtime — verifying DI, configuration loading, and module initialization.

Installation

<PackageReference Include="Silky.TestBase" Version="3.9.2" />
<PackageReference Include="xunit" Version="2.x.x" />
<PackageReference Include="Shouldly" Version="4.x.x" />  <!-- optional assertion library -->

Core Type: SilkyIntegratedTest<TStartupModule>

SilkyIntegratedTest<TStartupModule> is the base class for all integration test classes. The generic parameter TStartupModule is the test-specific module entry point.

On construction, the base class:

  1. Creates a host environment (default name: Testing)
  2. Reads config files (appsettings.json, appsettings.Testing.json, etc.)
  3. Builds the Autofac container and runs full module initialization
  4. Exposes ServiceProvider, Configuration, Engine, and other properties
MemberDescription
ServiceProviderRoot service container (IServiceProvider)
TestServiceScopeTest service scope (IServiceScope)
ConfigurationTest environment IConfiguration
EngineSilky engine instance (IEngine)
GetRequiredService<T>()Resolve a service from the test scope
BeforeAddApplication(services)Hook: add registrations before module init
AfterAddApplication(services)Hook: add registrations after module init
CreateConfigurationBuilder()Hook: customize configuration building
CreateHostEnvironment()Hook: customize the test host environment

On test class disposal, Dispose() automatically closes TestServiceScope and releases all Scoped services.

Basic Usage

Step 1: Create a Test Module

using Silky.Core.Modularity;

[DependsOn(
    typeof(OrderApplicationModule),
    typeof(AccountApplicationModule)
)]
public class OrderTestModule : SilkyModule
{
    // Override ConfigureServices or Initialize for test-specific setup
}

Step 2: Create a Test Class

using Silky.TestBase;
using Shouldly;
using Xunit;

public class OrderAppServiceTests : SilkyIntegratedTest<OrderTestModule>
{
    private readonly IOrderAppService _orderAppService;

    public OrderAppServiceTests()
    {
        _orderAppService = GetRequiredService<IOrderAppService>();
    }

    [Fact]
    public async Task CreateOrder_WithValidInput_ShouldSucceed()
    {
        // Arrange
        var input = new CreateOrderInput
        {
            ProductId = 1,
            Quantity = 2,
            Address = "123 Main St"
        };

        // Act
        var result = await _orderAppService.CreateOrderAsync(input);

        // Assert
        result.ShouldNotBeNull();
        result.Id.ShouldBeGreaterThan(0);
    }

    [Fact]
    public async Task GetOrder_WithInvalidId_ShouldThrow()
    {
        await Should.ThrowAsync<EntityNotFoundException>(
            () => _orderAppService.GetAsync(999999));
    }
}

Test Configuration

Place test-specific configuration in appsettings.Testing.json:

{
  "ConnectionStrings": {
    "Default": "Server=localhost;Database=TestDb;..."
  },
  "Redis": {
    "Configuration": "localhost:6379"
  }
}

Mocking Dependencies

Override BeforeAddApplication to substitute mock implementations:

public class OrderAppServiceTests : SilkyIntegratedTest<OrderTestModule>
{
    protected override void BeforeAddApplication(IServiceCollection services)
    {
        // Replace the real payment service with a mock
        services.AddSingleton<IPaymentService, MockPaymentService>();
    }
}

Parallel Test Isolation

xUnit test classes run in parallel by default. Each SilkyIntegratedTest instance creates its own TestServiceScope, so Scoped services are isolated between test classes. Use [Collection] groups to prevent resource conflicts (e.g., shared database):

[Collection("Database")]
public class OrderRepositoryTests : SilkyIntegratedTest<OrderTestModule> { }

[Collection("Database")]
public class ProductRepositoryTests : SilkyIntegratedTest<ProductTestModule> { }

Warning

Do not commit TestResults/, bin/, or obj/ directories to source control.

Edit this page
Prev
Message Bus (MassTransit)