Aracılığıyla paylaş


ile birim testi Orleans

Bu öğreticide, doğru davrandığından emin olmak için taneciklerinizin birim testinin nasıl yapılacağını gösterir. Taneciklerinizi birleştirilmiş test etmenin iki ana yolu vardır ve seçtiğiniz yöntem test ettiğiniz işlevselliğin türüne bağlıdır. Microsoft..Orleans. TestingHost NuGet paketi, tanecikleriniz için test siloları oluşturmak için kullanılabilir veya hub'ınızın etkileşimde olduğu çalışma zamanının Orleans parçalarını taklit etmek için Moq gibi sahte bir çerçeve kullanabilirsiniz.

TestCluster kullanın

Microsoft.Orleans.TestingHost NuGet paketi, varsayılan olarak iki silodan oluşan ve tanecikleri test etmek için kullanılabilen bir bellek içi küme oluşturmak için kullanılabilecek paketi içerirTestCluster.

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);
    }
}

Bellek içi küme başlatma ek yükünden dolayı, bir oluşturup TestCluster birden çok test çalışması arasında yeniden kullanmak isteyebilirsiniz. Örneğin, bu xUnit'in sınıfı veya koleksiyon fikstürleri kullanılarak yapılabilir.

Birden çok test çalışması arasında bir TestCluster paylaşmak için önce bir fikstür türü oluşturun:

using Orleans.TestingHost;

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

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

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

Ardından, bir koleksiyon fikstür oluşturun:

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

Artık test çalışmalarınızda bir'i TestCluster yeniden kullanabilirsiniz:

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, tüm testler tamamlandığında ve bellek içi küme siloları durdurulduğunda türün yöntemini ClusterFixture çağırırDispose(). TestCluster ayrıca, kümedeki siloları TestClusterOptions yapılandırmak için kullanılabilecek kabul eden bir oluşturucuya sahiptir.

Hizmetleri Grains'in kullanımına açmak için Silo'nuzda Bağımlılık Ekleme özelliğini kullanıyorsanız şu deseni de kullanabilirsiniz:

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>(/* ... */);
        });
    }
}

Sahteleri kullanma

Orleans ayrıca sistemin birçok parçasıyla dalga geçmeyi mümkün kılar ve birçok senaryo için test tanelerini birleştirmenin en kolay yolu budur. Bu yaklaşımın sınırlamaları vardır (örneğin, zamanlama yeniden giriş ve serileştirme ile ilgili) ve taneciklerin yalnızca birim testleriniz tarafından kullanılan kodu içermesini gerektirebilir. Orleans TestKit, bu sınırlamaların çoğunu yan adımlarla uygulayan alternatif bir yaklaşım sağlar.

Örneğin, test ettiğiniz tahılın diğer tahıllarla etkileşime geçtiğini düşünün. Diğer tahıllarla dalga geçebilmek için, test altındaki tahılın üyesiyle de dalga geçmeniz GrainFactory gerekir. Varsayılan olarak GrainFactory normal protected bir özelliktir, ancak çoğu sahte çerçeve, özelliklerin bunların sahte olmasını public ve virtual taklit edebilmesini gerektirir. Bu nedenle yapmanız gereken ilk şey hem hem public virtual de özelliğini oluşturmaktırGrainFactory:

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

Artık tahılınızı çalışma zamanının Orleans dışında oluşturabilir ve davranışını GrainFactorydenetlemek için sahtesini kullanabilirsiniz:

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());
    }
}

Burada, Moq kullanarak testin WorkerGrainaltındaki dilimi oluşturursunuz. Bu, öğesinin GrainFactory davranışını geçersiz kılarak sahte IJournalGrainbir sonuç döndürebileceğiniz anlamına gelir. Ardından öğesinin WorkerGrain ile beklediğiniz gibi etkileşimde IJournalGrain bulunduğunu doğrulayabilirsiniz.