如何单元测试Akka.Net Actor State(使用Become())

时间:2016-07-18 20:52:28

标签: unit-testing akka.net

我有一个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。坚持您在应用程序中实际使用的测试中的消息传递模型。

1 个答案:

答案 0 :(得分:2)

您可以通过消息传递对此进行正常测试。例如,您在“已启动”状态下处理了哪些消息?我假设您的示例已简化为已启动的Console.WriteLine操作。

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

作为一个简单的建议:

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

如果在处于启动状态时收到StartMessage,则可以在收到AlreadyStarted消息时断言。

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