如何在 Akka.NET 中使用 TestKit

2024-04-19

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

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

我用来参考的测试是ReceiveActorTests.cs https://github.com/akkadotnet/akka.net/blob/ce561dd51755e0b46f429d092691e494232fb811/src/core/Akka.Tests/Actor/ReceiveActorTests.cs and ReceiveActorTests_Become.cs https://github.com/akkadotnet/akka.net/blob/ce561dd51755e0b46f429d092691e494232fb811/src/core/Akka.Tests/Actor/ReceiveActorTests_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 https://github.com/akkadotnet/akka.net/blob/ce561dd51755e0b46f429d092691e494232fb811/src/core/Akka.Tests/Actor/ReceiveActorTests_Become.cs测试,演员是由

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 系统的上下文中按预期工作。这更像是黑盒测试——你无法直接接触演员的内部。相反,最好关注诸如以下行为:给定信号 A 和参与者行为 B,它应该向另一个参与者 D 发出消息 C.

在你的示例问题中Greeteractor 的特点是它是静音的 - 虽然它可以接收一些输入,但它不会执行任何结果。从整个系统的角度来看,它可能已经死了,没有人会关心。

使用其他示例 - 给出以下演员:

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 的内部状态。相反,我观察它对我发送给它的信号的反应,并验证它是否是预期的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Akka.NET 中使用 TestKit 的相关文章

随机推荐

  • SQL数据库自动备份[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个 SQL 数据库 我需要每天 至少 备份它 最好每天多次 自动 这样它肯定会完成 我正在运行
  • emacs - 如何在子目录中进行查找文件搜索

    我想为 Emacs 实现类似 Resharper 的 转到文件 功能 当按下上述快捷键时 Resharper 会弹出一个接受通配符字符串的文本框 并显示一个自动完成菜单 其中列出了项目中与该通配符匹配的所有文件 source jetbrai
  • 鼠标悬停时显示链接

    我有页面的某些区域 单击这些区域时 会将用户重定向到某些地址 我的问题是 当用户 将鼠标悬停在 这些区域上时 他们会看到一个指针 但不知道它链接到哪里 就我的目的而言 用户知道他们被链接到哪里是很重要的 我相信当您将鼠标悬停在链接上时 Go
  • 保存图片到mongodb

    我正在尝试使用龙卷风 石油和 mongodb 来做到这一点 avat self request files avatar 0 body nomfich self request files avatar 0 filename try ima
  • Symfony2 Doctrine2 内存泄漏/超出内存限制

    我在symfony2和doctrine2的结合上遇到了很多麻烦 我必须处理巨大的数据集 大约 2 3 百万次写入和读取 并且必须做大量额外的工作以避免内存不足 我找出了两个要点 即 泄漏 内存 它们实际上并不是真正泄漏 而是分配了很多内存
  • 优化缓慢的 ORDER BY RAND() 查询

    我有一个正在使用的查询ORDER BY RAND 但这需要太长时间 而且随着数据的增长 情况会变得更糟 该查询连接两个表 返回 5 个随机产品以及每个产品的随机图像 表 1 产品 product id pk auto inc name de
  • 下载文件 java spring Rest api

    我想制作一个rest api控制器 spring boot 当用get请求时将允许我下载一个excel文件 目前我有这个端点 RequestMapping value download xls method RequestMethod GE
  • 如何在 Bash 中保留带引号的字符串中的换行符? [复制]

    这个问题在这里已经有答案了 我正在创建一个脚本来自动创建 apache 虚拟主机 我的脚本的一部分是这样的 MYSTRING
  • 在Android中使用AudioTrack播放WAV文件

    我正在使用 Android 试图让我的 AudioTrack 应用程序播放 Windows wav 文件 Tada wav 坦率地说 这不应该这么难 但我听到了很多奇怪的事情 该文件保存在我手机的迷你 SD 卡上 读取内容似乎不是问题 但是
  • Eclipselink 生成的规范元模型不会从另一个 jar 扩展基本元模型

    我使用 Netbeans 8 0 1 创建了两个 Maven 项目来说明问题 common1 和 common2 jar common1 封装包1 MappedSuperclass public class Entity1 implemen
  • 符号被认为是标识符,而不是运算符

    我想实现一个在我的软件中使用的货币运算符 它接受 Double 并返回货币类型以进行更精确的计算 自定义运算符的代码基本上看起来有点像这样 请忽略这种形式中明显的精度下降以及因此无用的运算符 postfix operator postfix
  • 为 Phusion Passenger 应用程序设置环境变量

    我已经在开发中设置了 Passenger Mac OS X 并且它运行完美 后来唯一的问题来了 现在我有一个自定义的GEM HOME路径和 ImageMagick 二进制文件安装在 usr local 我可以将它们放入获取源的 shell
  • regexp_split_to_table 和 row_number

    我有一个包含字符串数据的表 如下所示 id string data 1 red green blue 2 orange 3 purple cyan 我需要将字符串数据拆分为具有行号的项目 id num item 1 1 red 1 2 gr
  • Chrome 在调整大小时无法正确更新背景大小渐变

    虽然 Firefox 正确地做到了这一点 但更新了linear gradient每一帧上的背景 chrome 似乎都会以 跳跃 的方式渲染事物 这意味着它只会在调整大小后每隔几个像素渲染一次数学上正确的布局 演示游乐场 http jsbin
  • 如何使用 Haskell 创建符号链接?

    如何使用 Haskell 创建符号链接 这directory据我所知 包没有提供一种方法来做到这一点 Creating a symbolic link is non portable For example the creation sym
  • 当记录处理时间超过“max.poll.interval.ms”时,在消费过程中记录/消息会发生什么?

    我的消费者设置如下 auto offset reset earliest enable auto commit true default value session timeout ms 10000 default value max po
  • 如何让 nginx 和乘客在部署后自动重启

    我目前在虚拟专用服务器上部署了一个 Rails 应用程序 我使用 Capistrano Nginx 和乘客在服务器上运行我的 Rails 应用程序 由于某种原因 在完成 cap 部署 更新后 我永远无法在网站上显示更新的代码 部署进行得很好
  • 使用 Zeep 解析 WSDL

    我想用 Zeep 解析 WSDL 文件并退出 所有操作 为每个操作请求 xml 消息 有解析 wsdl 的例子吗 我想我应该使用 zeep wsdl 和 parse service 方法 A updated import operator
  • JPA Criteria API:用于可选关系的 LEFT JOIN

    我基本上是第一次使用 Criteria API 这是关于抽象通用构建器的查询 public TypedQuery
  • 如何在 Akka.NET 中使用 TestKit

    我正在尝试测试我的 Akka NET Actor 但在使用 TestKit 和理解它的工作原理时遇到了一些问题 由于 Akka NET 中还没有关于单元测试的官方文档 我已经探索了 Akka NET 存储库中的示例代码 但那里使用的示例对我