如何使用状态对 Service Fabric Actor 进行单元测试
How to unit test Service Fabric Actor with State
我已经开始为具有状态的新 actor 编写单元测试。状态在激活 Actor 时由 Service Fabric 调用的 OnActivateAsync 方法中初始化。
进行单元测试时,我自己创建了 Actor,并且由于该方法受到保护,我无法从我的单元测试中访问自己来调用此方法。
我想知道这种测试的常用方法。我可以模拟 Actor 和模拟状态,但对于我想测试的代码调用原始代码。我想知道是否还有另一种我没有遇到过的方法。
另一种方法是将 State 初始化移动到其他地方,例如 public 方法或构造函数中,但 Actor 的模板在那里有代码,因此这可能是最佳实践。
我知道这并不理想,但您可以使用反射来调用 OnActivateAsync()
方法。
例如,
var method = typeof(ActorBase).GetMethod("OnActivateAsync", BindingFlags.Instance | BindingFlags.NonPublic);
await (Task)method.Invoke(actor, null);
这样您将测试您想要测试的实际方法,也不会公开您不想公开的方法。
您可能会发现将 actor 的创建和对 OnActivateAsync()
的手动调用组合到一个方法中很有用,这样它就可以在您的测试套件中使用并模仿原始的 Service Fabric 行为。
我喜欢在 actor 上使用 InternalsVisibleTo 属性和调用 OnActivateAsync 方法的内部方法。
在目标Actor项目中,AssemblyInfo.cs添加这样一行:
[assembly: InternalsVisibleTo("MyActor.Test")]
其中 "MyActor.Test" 是您要授予内部成员访问权限的测试项目的名称。
在目标 Actor class 中添加如下方法:
internal Task InvokeOnActivateAsync()
{
return OnActivateAsync();
}
这样您就可以从您的测试项目调用 OnActivateAsync 方法,如下所示:
var actor = CreateNewActor(id);
actor.InvokeOnActivateAsync()
使用最新版本的 ServiceFabric.Mocks NuGet 包。它包含调用 OnActivateAsync 保护方法的特殊扩展和用于 ServiceFabric 单元测试的整个工具集。
var svc = MockActorServiceFactory.CreateActorServiceForActor<MyActor>();
var actor = svc.Activate(new ActorId(Guid.NewGuid()));
actor.InvokeOnActivateAsync().Wait();
我已经开始为具有状态的新 actor 编写单元测试。状态在激活 Actor 时由 Service Fabric 调用的 OnActivateAsync 方法中初始化。
进行单元测试时,我自己创建了 Actor,并且由于该方法受到保护,我无法从我的单元测试中访问自己来调用此方法。
我想知道这种测试的常用方法。我可以模拟 Actor 和模拟状态,但对于我想测试的代码调用原始代码。我想知道是否还有另一种我没有遇到过的方法。
另一种方法是将 State 初始化移动到其他地方,例如 public 方法或构造函数中,但 Actor 的模板在那里有代码,因此这可能是最佳实践。
我知道这并不理想,但您可以使用反射来调用 OnActivateAsync()
方法。
例如,
var method = typeof(ActorBase).GetMethod("OnActivateAsync", BindingFlags.Instance | BindingFlags.NonPublic);
await (Task)method.Invoke(actor, null);
这样您将测试您想要测试的实际方法,也不会公开您不想公开的方法。
您可能会发现将 actor 的创建和对 OnActivateAsync()
的手动调用组合到一个方法中很有用,这样它就可以在您的测试套件中使用并模仿原始的 Service Fabric 行为。
我喜欢在 actor 上使用 InternalsVisibleTo 属性和调用 OnActivateAsync 方法的内部方法。
在目标Actor项目中,AssemblyInfo.cs添加这样一行:
[assembly: InternalsVisibleTo("MyActor.Test")]
其中 "MyActor.Test" 是您要授予内部成员访问权限的测试项目的名称。
在目标 Actor class 中添加如下方法:
internal Task InvokeOnActivateAsync()
{
return OnActivateAsync();
}
这样您就可以从您的测试项目调用 OnActivateAsync 方法,如下所示:
var actor = CreateNewActor(id);
actor.InvokeOnActivateAsync()
使用最新版本的 ServiceFabric.Mocks NuGet 包。它包含调用 OnActivateAsync 保护方法的特殊扩展和用于 ServiceFabric 单元测试的整个工具集。
var svc = MockActorServiceFactory.CreateActorServiceForActor<MyActor>();
var actor = svc.Activate(new ActorId(Guid.NewGuid()));
actor.InvokeOnActivateAsync().Wait();