Sdílet prostřednictvím


Testování jednotek s využitím Orleans

V tomto kurzu se dozvíte, jak testovat zrnka, aby se ujistila, že se chovají správně. Existují dva hlavní způsoby testování zrn a zvolená metoda bude záviset na typu funkce, kterou testujete. Microsoft.Orleans. Balíček TestingHost NuGet lze použít k vytvoření testovacích sila pro vaše zrní, nebo můžete použít napodobenou architekturu Orleans napodobování částí modulu runtime, se kterými interaguje vaše zrnitost.

Použít TestCluster

Balíček Microsoft.Orleans.TestingHost NuGet obsahuje TestCluster , který lze použít k vytvoření clusteru v paměti, který se ve výchozím nastavení skládá ze dvou sila, které lze použít k testování zrn.

using Orleans.TestingHost;

namespace Tests;

public class HelloGrainTests
{
    [Fact]
    public async Task SaysHelloCorrectly()
    {
        var builder = new TestClusterBuilder();
        var cluster = builder.Build();
        cluster.Deploy();

        var hello = cluster.GrainFactory.GetGrain<IHelloGrain>(Guid.NewGuid());
        var greeting = await hello.SayHello("World");

        cluster.StopAllSilos();

        Assert.Equal("Hello, World!", greeting);
    }
}

Kvůli režii při spuštění clusteru v paměti můžete chtít vytvořit TestCluster cluster a znovu ho použít v několika testovacích případech. Můžete to například provést pomocí třídy xUnit nebo zařízení kolekce.

Pokud chcete sdílet TestCluster více testovacích případů, nejprve vytvořte typ zařízení:

using Orleans.TestingHost;

public sealed class ClusterFixture : IDisposable
{
    public TestCluster Cluster { get; } = new TestClusterBuilder().Build();

    public ClusterFixture() => Cluster.Deploy();

    void IDisposable.Dispose() => Cluster.StopAllSilos();
}

Dále vytvořte zařízení kolekce:

[CollectionDefinition(Name)]
public sealed class ClusterCollection : ICollectionFixture<ClusterFixture>
{
    public const string Name = nameof(ClusterCollection);
}

V testovacích případech teď můžete znovu použít TestCluster :

using Orleans.TestingHost;

namespace Tests;

[Collection(ClusterCollection.Name)]
public class HelloGrainTestsWithFixture(ClusterFixture fixture)
{
    private readonly TestCluster _cluster = fixture.Cluster;

    [Fact]
    public async Task SaysHelloCorrectly()
    {
        var hello = _cluster.GrainFactory.GetGrain<IHelloGrain>(Guid.NewGuid());
        var greeting = await hello.SayHello("World");

        Assert.Equal("Hello, World!", greeting);
    }
}

xUnit volá Dispose() metodu ClusterFixture typu, když byly dokončeny všechny testy a jsou zastaveny sila clusteru v paměti. TestCluster má také konstruktor, který přijímá TestClusterOptions , že lze použít ke konfiguraci sila v clusteru.

Pokud ke zpřístupnění služeb pro Zrna používáte injektáž závislostí, můžete použít také tento vzor:

using Microsoft.Extensions.DependencyInjection;
using Orleans.TestingHost;

namespace Tests;

public sealed class ClusterFixtureWithConfig : IDisposable
{
    public TestCluster Cluster { get; } = new TestClusterBuilder()
        .AddSiloBuilderConfigurator<TestSiloConfigurations>()
        .Build();

    public ClusterFixtureWithConfig() => Cluster.Deploy();

    void IDisposable.Dispose() => Cluster.StopAllSilos();
}

file sealed class TestSiloConfigurations : ISiloConfigurator
{
    public void Configure(ISiloBuilder siloBuilder)
    {
        siloBuilder.ConfigureServices(static services =>
        {
            // TODO: Call required service registrations here.
            // services.AddSingleton<T, Impl>(/* ... */);
        });
    }
}

Použití napodobení

Orleans umožňuje také napodobení mnoha částí systému a v mnoha scénářích je to nejjednodušší způsob, jak testovat zrnka. Tento přístup má omezení (například plánování opětovného vytváření a serializace) a může vyžadovat, aby zrnka obsahovala kód používaný pouze testy jednotek. Sada Orleans TestKit nabízí alternativní přístup, který nabízí souběžné kroky těchto omezení.

Představte si například, že agregační interval, který testujete, komunikuje s jinými zrnky. Chcete-li být schopni napodobení těchto dalších zrn, musíte také napodobeniny GrainFactory člena zrnitého testu. Ve výchozím nastavení GrainFactory je normální protected vlastnost, ale většina architektur napodobování vyžaduje, aby vlastnosti byly public a virtual aby je bylo možné napodobovat. Takže první věc, kterou potřebujete udělat, je vytvořit GrainFactory jak vlastnost public virtual , tak i:

public new virtual IGrainFactory GrainFactory
{
    get => base.GrainFactory;
}

Teď můžete vytvořit zrnko mimo Orleans modul runtime a pomocí napodobování řídit chování GrainFactory:

using Xunit;
using Moq;

namespace Tests;

public class WorkerGrainTests
{
    [Fact]
    public async Task RecordsMessageInJournal()
    {
        var data = "Hello, World";
        var journal = new Mock<IJournalGrain>();
        var worker = new Mock<WorkerGrain>();
        worker
            .Setup(x => x.GrainFactory.GetGrain<IJournalGrain>(It.IsAny<Guid>()))
            .Returns(journal.Object);

        await worker.DoWork(data)

        journal.Verify(x => x.Record(data), Times.Once());
    }
}

Zde vytvoříte zrnko pod testem , WorkerGrainpomocí Moq, což znamená, že můžete přepsat chování GrainFactory tak, aby vrátil napodobeno IJournalGrain. Pak můžete ověřit, že WorkerGrain interakce s očekávaným IJournalGrain způsobem probíhá.