【问题标题】:How to unit test Akka.Net Actor State (using Become())如何对 Akka.Net Actor State 进行单元测试(使用成为())
【发布时间】:2016-07-18 20:52:27
【问题描述】:

我有一个 Actor,当它收到 StartMessage 时,它应该使用 Become(Started) 更改状态。如何对 Actor 的状态是否已更改为 Started() 进行单元测试?

MyActor 类

public class MyActor : ReceiveActor
{
    public MyActor()
    {
        Receive<StartMessage>(s => {
            Become(Started); // This is what I want to unit test
        });
    }

    private void Started()
    {
        Console.WriteLine("Woo hoo! I'm started!");
    }
}

单元测试

        [TestMethod]
    public void My_actor_changes_state_to_started()
    {
        // Arrange
        var actor = ActorOfAsTestActorRef<MyActor>(Props.Create(() => new MyActor()));

        // Act
        actor.Tell(new StartMessage());

        // Assert
        var actorsCurrentState = actor.UnderlyingActor.STATE; // <-- This doesn't work
        Assert.AreEqual(Started, actorsCurrentState);
    }

更新

与 tomliversidge 的回答有关:我编写此单元测试的原因是学术性的,但实际上,这不是一个好的单元测试,这就是为什么您无法按照我希望的那样进行。来自Petabridge's Unit Testing Guide

实际上,如果一个参与者想知道另一个参与者的内部状态,那么它必须向该参与者发送一条消息。我建议您在测试中遵循相同的模式,不要滥用 TestActorRef。在您的测试中坚持您在应用程序中实际使用的消息传递模型。

【问题讨论】:

    标签: unit-testing akka.net


    【解决方案1】:

    您通常会通过消息传递来测试它。例如,您在 Started 状态下处理哪些消息?我假设您的示例已简化为 Started 内的 Console.WriteLine 操作。

    如果您发送 StartMessage,然后在 Started 状态下处理第二条消息,则您可以断言对该第二条消息的响应。

    作为一个简单的建议:

    private void Started()
    {
        Receive<StartMessage>(msg => {
            Sender.Tell(new AlreadyStarted());
        } 
    }
    

    如果在 Started 状态下收到 StartMessage,您可以在收到 AlreadyStarted 消息时断言。

    有关更多信息,请查看 Petabridge 文章 https://petabridge.com/blog/how-to-unit-test-akkadotnet-actors-akka-testkit/

    【讨论】:

    • 我已经从前到后阅读了 Petebridge 的单元测试指南几次 :-) 我将用一些支持你答案的措辞来更新我的问题。我希望会有一个不同的答案,但我认为你已经确认你正在编写这样的单元测试的场景可能表明代码有异味
    • 是的,最好坚持黑盒消息传递:)
    猜你喜欢
    • 2016-06-02
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 2014-10-26
    相关资源
    最近更新 更多