Akka.使用TestKit创建/监督网络测试子角色
本文关键字:网络 测试 角色 使用 TestKit 创建 Akka | 更新日期: 2023-09-27 18:18:53
我有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);
}
}
}
我已经得到了这个测试工作,但我显然错过了一些东西,因为我根本没有使用太多的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);
}
我应该如何创建模拟演员?我可以调用TestKit上的任何方法来等待所有消息被处理?
引自《如何测试Akka》。. NET演员:单元测试w/Akka.TestKit
:
测试父/子关系更复杂。这是Akka。. NET对提供简单抽象的承诺使得测试更加困难。
测试这种关系最简单的方法是使用消息传递。例如,您可以创建一个父参与者,它的子参与者一旦启动就会向另一个参与者发送消息。或者你可以让父节点转发一条消息给子节点,然后子节点可以回复原始发送者,例如:
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!"); } }
关于测试亲子关系的警告
避免将代码与层次结构过度耦合!
过度测试父/子关系可以将测试与层次结构实现耦合。这增加了稍后重构代码的成本,因为它会迫使许多测试重写。你需要在验证你的意图和测试你的实现之间取得平衡。