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ı GrainFactory
denetlemek 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 WorkerGrain
altındaki dilimi oluşturursunuz. Bu, öğesinin GrainFactory
davranışını geçersiz kılarak sahte IJournalGrain
bir sonuç döndürebileceğiniz anlamına gelir. Ardından öğesinin WorkerGrain
ile beklediğiniz gibi etkileşimde IJournalGrain
bulunduğunu doğrulayabilirsiniz.