Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Den här självstudien visar hur du enhetstestar dina korn för att se till att de fungerar korrekt. Det finns två huvudsakliga sätt att enhetstesta dina korn, och vilken metod du väljer beror på vilken typ av funktionalitet du testar. Använd Microsoft.Orleans.TestingHost NuGet-paketet för att skapa testsilor för dina grains, eller använd ett mock-ramverk som Moq för att mocka delar av Orleans-runtime som ditt grain interagerar med.
Använd TestCluster
Microsoft.Orleans.TestingHost NuGet-paketet innehåller TestCluster, som du kan använda för att skapa ett minnesinternt kluster (bestående av två silor som standard) för testning av korn.
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);
}
}
På grund av kostnaden för att starta ett minnesinternt kluster kanske du vill skapa ett TestCluster och återanvända det bland flera testfall. Du kan till exempel uppnå detta med hjälp av xUnits klass- eller samlingsfixturer.
Om du vill dela en TestCluster mellan flera testfall skapar du först en typ av fixtur:
using Orleans.TestingHost;
public sealed class ClusterFixture : IDisposable
{
public TestCluster Cluster { get; } = new TestClusterBuilder().Build();
public ClusterFixture() => Cluster.Deploy();
void IDisposable.Dispose() => Cluster.StopAllSilos();
}
Skapa sedan en samlingsfixtur:
[CollectionDefinition(Name)]
public sealed class ClusterCollection : ICollectionFixture<ClusterFixture>
{
public const string Name = nameof(ClusterCollection);
}
Nu kan du återanvända en TestCluster i dina testfall:
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);
}
}
När alla tester har slutförts och de minnesinterna klusters silor stoppas anropar xUnit Dispose() metod från ClusterFixture typen.
TestCluster har också en konstruktor som accepterar TestClusterOptions att du kan använda för att konfigurera silor i klustret.
Om du använder Dependency Injection i din Silo för att göra tjänster tillgängliga för Grains kan du också använda det här mönstret:
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>(/* ... */);
});
}
}
Använd mocks
Orleans gör det också möjligt att håna många delar av systemet. I många scenarier är det här det enklaste sättet att förena testkorn. Den här metoden har begränsningar (t.ex. kring schemaläggning av återaktivering och serialisering) och kan kräva att grains inkluderar kod som endast används av dina enhetstester. Orleans TestKit tillhandahåller en alternativ metod som kringgår många av dessa begränsningar.
Anta till exempel att kornet som du testar interagerar med andra korn. För att mocka de andra korn måste du också mocka GrainFactory medlemmen i kornet under testning. Som standard är GrainFactory en normal protected egenskap, men de flesta mockingramverk kräver att egenskaperna är public och virtual för att möjliggöra mockning. Så det första steget är att göra GrainFactory både public och virtual:
public new virtual IGrainFactory GrainFactory
{
get => base.GrainFactory;
}
Nu kan du skapa din aktör utanför körningstiden Orleans och använda mocking för att styra beteendet hos 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());
}
}
Skapa testobjektet WorkerGrain, med hjälp av Moq, här. Detta möjliggör att åsidosätta GrainFactory's beteende så att den returnerar en mockad IJournalGrain. Du kan sedan kontrollera att WorkerGrain interagerar med IJournalGrain som förväntat.