对于Azure Service Fabric状态服务,可以按如下方式注入IReliableStateManager
:
ServiceRuntime.RegisterServiceAsync("MyServiceType", context =>
{
IReliableStateManager stateManager = new ReliableStateManager(context);
return new MyService(stateManager);
}
通过这种方式,您可以在IStateManager
的单元测试中模拟MyService
。
对于有状态的演员来说,这似乎是不可能的。 IActorStateManager
只有一个内部实施:Microsoft.ServiceFabric.Actors.Runtime.ActorStateManager
。那么我如何对一个有状态的演员进行单元测试?
在我的actor方法的某个时刻,调用IActorStateManager
,但由于我无法注入此依赖项,因此单元测试似乎不可能。
有没有办法解决这个问题还是有另一种解决方案?
答案 0 :(得分:3)
不,IActorStateManager今天不能注射,但我们正在努力做到这一点。现在(不使用反射)你必须将你的状态操作包装在你可以注入的东西中,并将该调用调用到状态管理器中,然后你可以模拟它进行单元测试。
答案 1 :(得分:0)
我通常在具有IStateManager参数的构造函数的单独类中编写actor业务逻辑并实现我的actor接口。 Actor只是在actor实现类中包装,我测试的是actorImpl类而不是actor。看一下代码:
public interface IMyActor01 : IActor
{
Task<int> GetCountAsync();
Task SetCountAsync(int count);
}
public class MyActor01Impl : IMyActor01
{
private readonly IActorStateManager StateManager;
public MyActor01Impl(IActorStateManager stateManager)
{
this.StateManager = stateManager;
this.StateManager.TryAddStateAsync("count", 0);
}
public Task<int> GetCountAsync()
{
return this.StateManager.GetStateAsync<int>("count");
}
public Task SetCountAsync(int count)
{
return this.StateManager.AddOrUpdateStateAsync("count", count, (key, value) => count > value ? count : value);
}
}
[StatePersistence(StatePersistence.Persisted)]
internal class MyActor01 : Actor, IMyActor01
{
private MyActor01Impl Impl;
protected override Task OnActivateAsync()
{
ActorEventSource.Current.ActorMessage(this, "Actor activated.");
this.Impl = new MyActor01Impl(this.StateManager);
return Task.FromResult(true);
}
Task<int> IMyActor01.GetCountAsync()
{
return this.Impl.GetCountAsync();
}
Task IMyActor01.SetCountAsync(int count)
{
return this.Impl.SetCountAsync(count);
}
}
[TestFixture]
public class TestFixture01
{
[Test]
public void Test01()
{
//ARRANGE
var dictionary = new Dictionary<string, object>();
var impl = new MyActor01Impl(new StubStateManager(dictionary));
//ACT
impl.SetCountAsync(12).Wait();
//ASSERT
Assert.AreEquals(12, impl.GetCountAsync().Result);
//or
Assert.AreEquals(12, (int)dictionary["count"]);
}
}
如果需要,我可以共享StubStateManager实现。