gpt4 book ai didi

c# - 如何在 Akka.NET 中使用 TestKit

转载 作者:可可西里 更新时间:2023-11-01 08:56:17 25 4
gpt4 key购买 nike

我正在尝试测试我的 Akka.NET actors,但在使用 TestKit 和理解它的工作原理时遇到了一些问题。

由于 Akka.NET 中还没有关于单元测试的官方文档,我已经探索了 Akka.NET 存储库以获取示例代码,但那里使用的示例对我不起作用。

我引用的测试是ReceiveActorTests.csReceiveActorTests_Become.cs ,因为这些与我尝试在我的应用中测试的场景很接近。

这是一些伪代码:

给定这个 Actor

public class Greeter : ReceiveActor
{
public Greeter()
{
NotGreeted();
}

private void NotGreeted()
{
Receive<Greeting>(msg => Handle(msg));
}

private void Greeted()
{
Receive<Farewell>(msg => Handle(msg));
}

private void Handle(Greeting msg)
{
if (msg.Message == "hello")
{
Become(Greeted);
}
}

private void Handle(Farewell msg)
{
if (msg.Message == "bye bye")
{
Become(NotGreeted);
}
}
}

我想测试它是否正确接收了 Greeting 和 Farewell 消息,并正确进入 Become-states。看着 ReceiveActorTests_Become.cs测试,一个 Actor 是由

var system = ActorSystem.Create("test");
var actor = system.ActorOf<BecomeActor>("become");

消息由

发送并断言
actor.Tell(message, TestActor);
ExpectMsg(message);

但是,当我尝试使用这种方法来实例化一个 actor 以及许多其他基于 TestKit 方法(见下文)的方法时,我不断收到相同的测试失败错误:

Xunit.Sdk.TrueExceptionFailed: Timeout 00:00:03 while waiting for a message of type ConsoleApplication1.Greeting 
Expected: True
Actual: False

这是我的测试:

public class XUnit_GreeterTests : TestKit
{
[Fact]
public void BecomesGreeted()
{
//var system = ActorSystem.Create("test-system"); // Timeout error
//var actor = system.ActorOf<Greeter>("greeter"); // Timeout error
//var actor = ActorOfAsTestActorRef<Greeter>("greeter"); // Timeout error
//var actor = ActorOf(() => new Greeter(), "greeter"); // Timeout error
//var actor = Sys.ActorOf<Greeter>("greeter"); // Timeout error
//var actor = Sys.ActorOf(Props.Create<Greeter>(), "greeter"); // Timeout error
var actor = CreateTestActor("greeter"); // Works, but doesn't test my Greeter actor, but rather creates a generic TestActor (as I understand it)

var message = new Greeting("hello");

actor.Tell(message, TestActor);

ExpectMsg(message);
}
}

我还尝试将 ExpectMsg 行移动到 actor.Tell 行上方(因为在你对它采取行动之前进行预期更有意义,而不是在之后验证预期),但这也会导致超时错误。

我尝试过使用 NUnit 和 XUnit TestKits。

我可能忽略了一些非常基本的东西。

最佳答案

TestKit 用于更多的行为测试,以验证您的 actor 在整个 actor 系统的上下文中是否按预期工作。这更像是黑盒测试——您不会直接触及 Actor 的内部。相反,最好将注意力集中在诸如给定信号 A 和参与者行为 B 之类的行为上,它应该向另一个参与者 D 发送消息 C

在您的示例中,Greeter actor 的问题在于它是静音的 - 虽然它可以接收一些输入,但它不会做任何结果。从整个系统的角度来看,它可能已经死了,没人会在意。

使用其他示例 - 给定以下 Actor :

public class Greeter : ReceiveActor
{
public Greeter()
{
Receive<Greet>(greet =>
{
// when message arrives, we publish it on the event stream
// and send response back to sender
Context.System.EventStream.Publish(greet.Who + " sends greetings");
Sender.Tell(new GreetBack(Self.Path.Name));
});
}
}

让我们创建一个示例测试规范:

public class GreeterSpec : TestKit
{
private IActorRef greeter;

public GreeterSpec() : base()
{
greeter = Sys.ActorOf<Greeter>("TestGreeter");
}

[Fact]
public void Greeter_should_GreetBack_when_Greeted()
{
// set test actor as message sender
greeter.Tell(new Greet("John Snow"), TestActor);
// ExpectMsg tracks messages received by TestActors
ExpectMsg<GreetBack>(msg => msg.Who == "TestGreeter");
}

[Fact]
public void Greeter_should_broadcast_incoming_greetings()
{
// create test probe and subscribe it to the event bus
var subscriber = CreateTestProbe();
Sys.EventStream.Subscribe(subscriber.Ref, typeof (string));

greeter.Tell(new Greet("John Snow"), TestActor);

// check if subscriber received a message
subscriber.ExpectMsg<string>("John Snow sends greetings");
}
}

如您所见,这里我不检查 actor 的内部状态。相反,我正在观察它如何对我发送给它的信号使用react,并验证它是否是预期结果。

关于c# - 如何在 Akka.NET 中使用 TestKit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30730706/

25 4 0
文章推荐: c# - Unity3d c# - Vector3 作为默认参数
文章推荐: c# - 检查 IEnumerable 是否为 IEnumerable