简体   繁体   English

Akka.Net使用TestKit测试儿童演员的创建/监督

[英]Akka.Net test Child actor creation/supervision with TestKit

I have Akka.Net code similar to the following and I am trying to write tests for it: 我有与以下类似的Akka.Net代码,并且我正在尝试为其编写测试:

public class DoesSomethingActor : UntypedActor
{
    protected override void OnReceive(object message)
    {

    }
}

public class ForwardsMessagesActor : UntypedActor
{
    protected override void OnReceive(object message)
    {
        var actor = Context.ActorOf(Context.DI().Props<DoesSomethingActor>(), "DoesSomethingWorker");

        for (int i = 0; i < 5; i++)
        {
            actor.Tell(message + " " + i);
        }
    }
}

I have got this test working but I am clearly missing something since I am not using much of TestKit at all. 我已经进行了此测试,但是由于我根本没有使用太多TestKit,因此我显然缺少了一些东西。 Is there still no official documentation for how to test this using TestKit ? 尚无官方文档说明如何使用TestKit进行测试吗?

//creating actor mocks with Moq seems to confuse Akka - it just doesn't work 
//but creating mock classes manually like this, 
//then configuring them in the DI container works
public class DoesSomethingActorSpy : DoesSomethingActor
{
    public static List<object> ReceivedMessages = new List<object>();

    protected override void OnReceive(object message)
    {
        ReceivedMessages.Add(message);
    }
}

    [TestMethod]
    public void ForwardsMessagesActor_Creates5Messages()
    {
        //set up DI container to use DoesSomethingActorSpy as a child actor
        ContainerBuilder builder = new ContainerBuilder();
        builder.RegisterType<ForwardsMessagesActor>();
        builder.RegisterType<DoesSomethingActorSpy>().As<DoesSomethingActor>();
        IContainer container = builder.Build();

        var propsResolver = new AutoFacDependencyResolver(container, Sys);

        var actor = ActorOfAsTestActorRef<ForwardsMessagesActor>(propsResolver.Create<ForwardsMessagesActor>());

        actor.Tell("Test");

        //this looks wrong, I probably should be using something from TestKit
        Thread.Sleep(10);

        CollectionAssert.AreEquivalent(
            new[] { "Test 0", "Test 1", "Test 2", "Test 3", "Test 4" },
            DoesSomethingActorSpy.ReceivedMessages);
    }

How should I create mock actors? 我应该如何创建模拟演员? Is there any method on TestKit I can call to wait until all messages have been processed? 我可以调用TestKit上的任何方法来等待所有消息处理完毕吗?

Quoted from How to Test Akka.NET Actors: Unit Testing w/ Akka.TestKit : 引自“ 如何测试Akka.NET Actor:带有Akka.TestKit单元测试”

Testing the parent/child relationship is more complicated. 测试父子关系更加复杂。 This is one case where Akka.NET's commitment to providing simple abstractions makes testing harder. 在这种情况下,Akka.NET提供简单抽象的承诺使测试变得更加困难。

The simplest way to test this relationship is with messaging. 测试这种关系的最简单方法是使用消息传递。 For example, you can create a parent actor whose child messages another actor once it starts. 例如,您可以创建一个父角色,该角色的子角色一旦启动,其子对象便会向另一个角色发出消息。 Or you may have the parent forward a message to the child, and then the child can reply to the original sender, eg: 或者您可以让父母将消息转发给孩子,然后孩子可以回复原始发件人,例如:

 public class ChildActor : ReceiveActor { public ChildActor() { ReceiveAny(o => Sender.Tell("hello!")); } } public class ParentActor : ReceiveActor { public ParentActor() { var child = Context.ActorOf(Props.Create(() => new ChildActor())); ReceiveAny(o => child.Forward(o)); } } [TestFixture] public class ParentGreeterSpecs : TestKit { [Test] public void Parent_should_create_child() { // verify child has been created by sending parent a message // that is forwarded to child, and which child replies to sender with var parentProps = Props.Create(() => new ParentActor()); var parent = ActorOfAsTestActorRef<ParentActor>(parentProps, TestActor); parent.Tell("this should be forwarded to the child"); ExpectMsg("hello!"); } } 

A Word of Caution On Testing Parent/Child Relationships 关于测试父母/孩子关系的警告

Avoid over-coupling your code to your hierarchy! 避免将代码过度耦合到层次结构!

Over-testing parent/child relationships can couple your tests to your hierarchy implementation. 过度测试父子关系会将您的测试耦合到层次结构实现中。 This increases the costs of refactoring your code later on by forcing many test rewrites. 通过强制执行许多测试重写,这将增加以后重构代码的成本。 You need to strike a balance between verifying your intent and testing your implementation. 您需要在验证意图和测试实现之间取得平衡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM