Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
Ce tutoriel montre comment tester unitairement vos grains pour s’assurer qu’ils se comportent correctement. Il existe deux méthodes principales pour tester vos grains et la méthode que vous choisissez dépend du type de fonctionnalité que vous testez. Utilisez le package NuGet Microsoft.Orleans.TestingHost pour créer des silos de test pour vos grains ou utilisez une infrastructure de simulation telle que Moq pour simuler des parties du Orleans runtime avec lesquelles votre grain interagit.
Utiliser le TestCluster
Le Microsoft.Orleans.TestingHost
package NuGet contient TestCluster, que vous pouvez utiliser pour créer un cluster en mémoire (consistant en deux silos par défaut) pour tester les grains.
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);
}
}
En raison de la surcharge de démarrage d’un cluster en mémoire, vous pouvez créer un TestCluster
cluster en mémoire et le réutiliser parmi plusieurs cas de test. Par exemple, effectuez cette opération à l’aide des éléments de classe ou de collection de xUnit.
Pour partager une TestCluster
entre plusieurs cas de test, commencez par créer un type de fixture :
using Orleans.TestingHost;
public sealed class ClusterFixture : IDisposable
{
public TestCluster Cluster { get; } = new TestClusterBuilder().Build();
public ClusterFixture() => Cluster.Deploy();
void IDisposable.Dispose() => Cluster.StopAllSilos();
}
Ensuite, créez un élément de collection :
[CollectionDefinition(Name)]
public sealed class ClusterCollection : ICollectionFixture<ClusterFixture>
{
public const string Name = nameof(ClusterCollection);
}
Vous pouvez maintenant réutiliser un TestCluster
dans vos cas de test :
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);
}
}
Lorsque tous les tests se terminent et que les silos de cluster en mémoire s’arrêtent, xUnit appelle la méthode Dispose() du type ClusterFixture
.
TestCluster
a également un constructeur acceptant TestClusterOptions que vous pouvez utiliser pour configurer les silos dans le cluster.
Si vous utilisez l'injection de dépendance dans votre Silo pour rendre les services disponibles aux Grains, vous pouvez également utiliser ce patron :
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>(/* ... */);
});
}
}
Utiliser des fictives
Orleans permet également de simuler de nombreuses parties du système. Pour de nombreux scénarios, il s’agit du moyen le plus simple de tester les grains de test unitaire. Cette approche présente les limitations (par exemple, concernant la planification de la réentrance et de la sérialisation) et peut nécessiter que les grains incluent du code utilisé uniquement par vos tests unitaires. Le Orleans TestKit offre une approche alternative qui évite bon nombre de ces limitations.
Par exemple, imaginez que le grain que vous testez interagit avec d’autres grains. Pour simuler ces autres grains, vous devez également simuler le GrainFactory membre du grain testé. Par défaut, GrainFactory
est une propriété normale protected
, mais la plupart des frameworks de simulation nécessitent que les propriétés soient public
et virtual
pour activer la simulation. Ainsi, la première étape consiste à faire GrainFactory
à la fois public
et virtual
:
public new virtual IGrainFactory GrainFactory
{
get => base.GrainFactory;
}
Vous pouvez maintenant créer votre grain en dehors du runtime et utiliser le mocking pour contrôler le comportement de Orleans:
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());
}
}
Ici, créez le grain sous test, WorkerGrain
, à l’aide de Moq. Cela permet de remplacer le comportement de l’objet GrainFactory
afin qu’il retourne un objet simulé IJournalGrain
. Vous pouvez ensuite vérifier que WorkerGrain
interagit avec IJournalGrain
comme prévu.