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

前端之家收集整理的这篇文章主要介绍了c# – 如何在Akka.NET中使用TestKit前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图测试我的Akka.NET演员,但是对TestKit有一些麻烦,并了解它的工作原理.

由于Akka.NET目前没有用于单元测试的官方文档,所以我已经开发了Akka.NET repo代码,但是在这里使用的例子并不适用于我.

我用来参考的测试是ReceiveActorTests.csReceiveActorTests_Become.cs,因为那些接近我在我的应用程序中测试的场景.

这里有一些虚拟代码

给这个演员

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);
        }
    }
}

我想测试它正确接收到问候和告别消息,并进入正确的状态.看看ReceiveActorTests_Become.cs测试,一个演员是由…创建的

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

并发送和断言的消息

actor.Tell(message,TestActor);
ExpectMsg(message);

然而,当我尝试这种方法来实例化一个演员,还有许多其他的基于TestKit方法(见下文),我不断得到samme失败的测试错误

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用于进行更多的行为测试,以验证您的演员是否按照预期在整个演员系统的上下文中工作.这更像黑盒测试 – 你不直接到达演员的内部.相反,最好专注于给定信号A和演员行为B等行为,它应该向另一个演员D发出消息C.

在您的示例中,Greeter演员的问题是,它是静音的 – 虽然它可以接收到一些输入,但它不会在结果中做任何事情.从整个系统的角度来看,它可能会死亡,没有人会关心.

使用其他示例 – 给定以下演员:

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");
    }
}

你可以看到,这里我不检查演员的内部状态.相反,我正在观察它对我发送的信号的反应,并验证它是否是预期的结果.

猜你在找的C#相关文章