C# 服务结构单元测试和依赖注入
我不能仅仅通过调用一个可靠的服务/参与者的构造函数然后测试它的方法来测试它<代码>var testService=new SomeService()代码>引发NullReferenceException。那么,如何使用已部署的服务 我知道部署的SF可靠服务/参与者不是标准的.NET类,对部署的S/A进行单元测试可能是一个奇怪的想法 不管怎么说,我现在正试着试试 比如说。我刚刚部署了一个服务,在测试中我创建了一个代理对象,并将项添加到服务的输入队列中。然后我需要断言输入队列计数=1。如果我刚刚部署了一个服务,而没有其他客户机/服务/参与者使用它的输入队列,那么它就可以工作。但下一次测试失败,这就是问题所在。我需要使服务停止与其他使用者一起运行,删除它的队列,然后测试它。为此,我可以创建一些TestMode属性和一些方法,如PropareForTests/TestingCompleted,并在测试前后从测试客户端调用它们 这样做是个坏主意。也许有一些单元测试的指南?谢谢 更新: 在调查过程中,我发现了以下待办事项字符串:C# 服务结构单元测试和依赖注入,c#,web-services,unit-testing,azure,azure-service-fabric,C#,Web Services,Unit Testing,Azure,Azure Service Fabric,我不能仅仅通过调用一个可靠的服务/参与者的构造函数然后测试它的方法来测试它var testService=new SomeService()引发NullReferenceException。那么,如何使用已部署的服务 我知道部署的SF可靠服务/参与者不是标准的.NET类,对部署的S/A进行单元测试可能是一个奇怪的想法 不管怎么说,我现在正试着试试 比如说。我刚刚部署了一个服务,在测试中我创建了一个代理对象,并将项添加到服务的输入队列中。然后我需要断言输入队列计数=1。如果我刚刚部署了一个服务,而
/// TODO: Temporary property-injection for an IServiceProxyWrapper until constructor injection is available.
这是否意味着SF服务将改善其DI支持?参与者呢?实际上,您可以像在.NET中测试任何其他类一样测试可靠的服务和参与者!它们的特殊之处在于它们在底层平台中使用了某些钩子,但除此之外,您可以正常地实例化服务或actor类并对其调用方法 目前,可靠的服务更容易进行单元测试,因为平台的主要钩子状态管理器是一个可通过构造函数插入的接口 例如,您的服务类可能如下所示: 编辑:使用GA发布API(2.0.135)更新 然后您可以像这样测试您的服务类:
[TestMethod]
public TestMyMethod()
{
MockReliableStateManager stateManager = new MockReliableStateManager();
MyService target = new MyService(stateManager);
target.MyMethod();
// validate results and all that good stuff
}
我们有一个实际服务的完整工作示例,其中许多依赖项在GitHub上进行了单元测试:
此示例还包含IReliableStateManager和iReliableSdictionary模拟,您可以将其用作自己单元测试的起点。要在可靠的参与者中模拟状态管理器,可以执行以下操作: 实际上,
StateManager
此时尚未初始化。我们可以在调用OnActivateAsync
时得到它:
private IActorStateManager _stateManager;
// Unit tests can inject mock here.
public MyActor(IActorStateManager stateManager = null)
{
_stateManager = stateManager;
}
protected override async Task OnActivateAsync()
{
if (_stateManager == null)
{
_stateManager = StateManager;
}
}
只需确保在代码的其余部分始终使用
\u stateManager
,而不是使用这个。stateManager
谢谢,瓦茨拉夫!这正是我们所需要的。请查看更新。在RTM(Actors 2.0.135)中,Actor.StateManager
属性是只读的(无受保护集
)。我应该如何为我的actor类注入状态管理器依赖项?对于actor的提醒和计时器呢?我可以自己调用receiverEminederAsync
方法,但我需要验证对registerEminederAsync
(ActorBase上的受保护方法)的调用。似乎我们仍然不能像拉尔斯说的那样嘲笑州经理。有什么解决办法吗?如果我们真的看不到参与者对状态做了什么,我们如何对他们进行单元测试?@VaclavTurecek:你能提供一个例子,说明如何“注入你自己的状态管理接口来包装状态管理器”?构造函数依赖项注入现在实际上在参与者中可用!注册actor类型时,还可以注册一个“factory”,它实际上只是一个Func,您可以在其中创建actor类实例,从而控制actor的实例化,从而可以通过它注入依赖项。在“服务”中,您已经可以做到这一点,请查看我们在Party Cluster示例中是如何做到的:我写了一个关于使用unity进行依赖项注入的答案:@VaclavTurecek您的链接已断开
private readonly IActorStateManager _stateManager;
public MyActor(IActorStateManager stateManager = null)
{
_stateManager = stateManager ?? this.StateManager;
}
private IActorStateManager _stateManager;
// Unit tests can inject mock here.
public MyActor(IActorStateManager stateManager = null)
{
_stateManager = stateManager;
}
protected override async Task OnActivateAsync()
{
if (_stateManager == null)
{
_stateManager = StateManager;
}
}