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