我有一个非常简单的 FSM,它成功地完成了一次转换,但仅此而已。不知道是FSM有错误还是test类有错误。
这是一个带有单元测试的完全可重现的示例:
using Akka;
using Akka.Actor;
using Akka.TestKit;
using Akka.TestKit.Xunit;
using System.Diagnostics;
using Xunit;
class MyFsm : FSM<MyFsm.State, MyFsm.Data>
{
public MyFsm()
{
StartWith(State.Idle, new Data());
When(State.Idle, state =>
{
var eventWasHandled = state.FsmEvent.Match()
.With<MessageA>(message => { return; })
.WasHandled;
if (eventWasHandled)
{
Debug.WriteLine($"{State.Idle} => transitioning to {State.Busy}");
return GoTo(State.Busy);
}
else
{
Debug.WriteLine($"{State.Idle} => returning null");
return null;
}
});
When(State.Busy, state =>
{
var eventWasHandled = state.FsmEvent.Match()
.With<MessageB>(message => { return; })
.WasHandled;
if (eventWasHandled)
{
Debug.WriteLine($"{State.Busy} => transitioning to {State.Done}");
return GoTo(State.Done);
}
else
{
Debug.WriteLine($"{State.Busy} => returning null");
return null;
}
});
Initialize();
}
public enum State { Idle, Busy, Done }
public class Data { }
}
class MessageA { }
class MessageB { }
public class MyFsmTests : TestKit
{
[Fact]
public void Its_initial_state_is_Idle()
{
var myFsm = new TestFSMRef<MyFsm, MyFsm.State, MyFsm.Data>(Sys, Props.Create<MyFsm>());
Assert.Equal(MyFsm.State.Idle, myFsm.StateName);
}
[Fact]
public void It_transitions_to_the_Busy_state_after_receiving_MessageA()
{
var myFsm = new TestFSMRef<MyFsm, MyFsm.State, MyFsm.Data>(Sys, Props.Create<MyFsm>());
myFsm.SetState(MyFsm.State.Idle);
myFsm.Tell(new MessageA());
Assert.Equal(MyFsm.State.Busy, myFsm.StateName);
}
[Fact]
public void It_transitions_to_the_Done_state_after_receiving_MessageB_using_SetState()
{
var myFsm = new TestFSMRef<MyFsm, MyFsm.State, MyFsm.Data>(Sys, Props.Create<MyFsm>());
myFsm.SetState(MyFsm.State.Busy);
myFsm.Tell(new MessageB());
Assert.Equal(MyFsm.State.Done, myFsm.StateName);
}
[Fact]
public void It_transitions_to_the_Done_state_after_receiving_MessageB_without_using_SetState()
{
var myFsm = new TestFSMRef<MyFsm, MyFsm.State, MyFsm.Data>(Sys, Props.Create<MyFsm>());
myFsm.Tell(new MessageA());
myFsm.Tell(new MessageB());
Assert.Equal(MyFsm.State.Done, myFsm.StateName);
}
}
Idle => transitioning to Busy
Assert.Equal() Failure Expected: Done Actual: Busy
Busy => transitioning to Done
Assert.Equal() Failure Expected: Done Actual: Busy
Idle => transitioning to Busy
Busy => transitioning to Done
我已经多次浏览文档,但在代码中找不到任何明显的错误。我错过了什么?
最佳答案
看起来这里的问题是您实际上没有定义为 Done
的状态,据 FSM 所知。
您需要添加一个 When(State.Done, e => { ... })
处理程序,这将允许 FSM 转换到该行为并正确报告它。
关于c# - 为什么这个 FSM 只在一个状态转换时成功?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46588702/