我在使用 PersistAll 和 PersistAllAsync 方法的 ReceivePersistentActor 实现的某些单元测试中遇到了问题。
问题是,当使用 TestKit.NUnit 进行单元测试时,PersistAll/Async 调用从不调用其完成回调。但是,持久/异步调用工作正常,持久全部/异步调用在单元测试之外工作正常。
这与TestKit以及它尝试在CallingThreadDispatcher上运行事物的方式有关吗?
我不确定如何为使用 PersistAll/Async 的代码编写单元测试 - 由于从未调用回调(我有我的 Sender.Tell 代码),测试总是因超时而失败。
我没有做任何奇怪的事情 - 我正在使用内存日志和快照存储,它们在默认调度程序上运行(我尝试为这些使用调用线程调度程序,但随后在单元测试中没有任何效果)。
公共接口IEvent;
公共类测试:接收持久演员{
public class StringReceivedEvent:IEvent {}
public Test()
{
Console.WriteLine("Started"); // <-- This is seen, but the next console output is not - callback is never fired
Command<string>(message => {
Console.WriteLine($"Received {message}");
PersistAll(new List<IEvent>(){new StringReceivedEvent()}, @event => {
Console.WriteLine("Persisted event"); //<-- never see this
Sender.Tell(true); //<-- this never gets called
});
});
}
public override string PersistenceId => "test-id";
}
[TestFixture]
public class Tests : Akka.TestKit.NUnit.TestKit
{
IActorRef subject;
public PublishingTests() : base(ConfigurationFactory.Load().WithFallback(Akka.TestKit.Configs.TestConfigs.DefaultConfig))
{
}
[SetUp]
public void Setup() {
subject = ActorOf(Props.Create<Test>(), "My-Test-Actor");
}
[Test]
public void Can_Persist_Event_And_Send_Completion_Reply() {
subject.Tell("hello");
ExpectMsg<bool>(TimeSpan.FromSeconds(15)); //<---- This times out
}
}
我刚刚在一个新的 .NET Core 2.0 项目中尝试了您的代码(进行了一些轻微的修改以使其编译),它工作正常。
下面是完整的复制步骤。首先在命令行/PowerShell上:
mkdir akka-net-persistence-unit-testing-issue-so
cd akka-net-persistence-unit-testing-issue-so
# Install nunit template if not already done:
dotnet new -i NUnit3.DotNetNew.Template
dotnet new nunit -n TestProject
cd TestProject
dotnet add package Akka
dotnet add package Akka.Persistence
dotnet add package Akka.TestKit.Nunit
我现在有一个 .csproj 文件,如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Akka" Version="1.3.7" />
<PackageReference Include="Akka.Persistence" Version="1.3.7" />
<PackageReference Include="Akka.TestKit.NUnit" Version="1.3.2" />
<PackageReference Include="nunit" Version="3.10.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.1" />
</ItemGroup>
</Project>
然后,为了重现,我将所有代码放在一个文件中,如下所示:
using System;
using System.Collections.Generic;
using Akka.Actor;
using Akka.Configuration;
using Akka.Persistence;
using NUnit.Framework;
namespace TestProject
{
public interface IEvent {};
public class TestActor : ReceivePersistentActor
{
public class StringReceivedEvent : IEvent { }
public TestActor()
{
Console.WriteLine("Started");
Command<string>(message =>
{
Console.WriteLine($"Received {message}");
PersistAll(new List<IEvent>() { new StringReceivedEvent() }, @event =>
{
Console.WriteLine("Persisted event");
Sender.Tell(true); //<-- this is apparently getting called now!
});
});
}
public override string PersistenceId => "test-id";
}
[TestFixture]
public class PublishingTests : Akka.TestKit.NUnit.TestKit
{
IActorRef subject;
public PublishingTests() : base(ConfigurationFactory.Load().WithFallback(Akka.TestKit.Configs.TestConfigs.DefaultConfig))
{
}
[SetUp]
public void Setup()
{
subject = ActorOf(Props.Create<TestActor>(), "My-Test-Actor");
}
[Test]
public void Can_Persist_Event_And_Send_Completion_Reply()
{
subject.Tell("hello");
ExpectMsg<bool>(TimeSpan.FromSeconds(15)); //<---- This no longer times out :-)
}
}
}
然后,您应该能够再次从命令行测试代码:
dotnet test
给出输出:
Build started, please wait...
Build completed.
Test run for C:SourcePrivatSoTestakka-net-persistence-unit-testing-issue-soTestProjectbinDebugnetcoreapp2.0Test
Project.dll(.NETCoreApp,Version=v2.0)
Microsoft (R) Test Execution Command Line Tool Version 15.7.0-preview-20180320-02
Copyright (c) Microsoft Corporation. All rights reserved.
Starting test execution, please wait...
Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 2,8449 Seconds
我在UntypedPersistentActor和xUnit上遇到了类似的问题,但是在我将其更改为ReceivePersistentActor并重新启动Visual Studio以及其他事情后,它突然消失了,但是一次发生了太多事情,所以不幸的是,我无法为您提供一个很好的答案,确切地说我为解决它做了什么(也是我想尝试解决这个问题并在这里重现它的原因, 但我不能)。我希望一组完整的复制步骤以及工作项目的确切包版本对您有所帮助......