简体   繁体   English

我们如何在服务结构(无状态服务)上执行集成测试?

[英]How we can perform integration test on service fabric (stateless service)?

I'ld like to perform integration on stateless service in service fabric.Please help me on this. 我想在服务架构中对无状态服务进行集成。请帮我解决这个问题。 I have created the stateless service like c# web api. 我创建了像c#web api这样的无状态服务。

In order to perform integration tests on your Reliable Service there is a number of dependencies you need to mock and take care of. 为了对您的可靠服务执行集成测试,您需要模拟和处理许多依赖项。 You will not be able to test all situations or behavior of your service this way, the way the FabricRuntime hosts and runs services is difficult to replicate (without writing your own FabricRuntime equivalency). 您将无法以这种方式测试服务的所有情况或行为, FabricRuntime托管和运行服务的方式很难复制(无需编写自己的FabricRuntime等效项)。 It is also worth noting that there is no way to run FabricRuntime without a cluster (including local development cluster). 值得注意的是,没有集群(包括本地开发集群)就无法运行FabricRuntime

You also need to consider how advanced your integration tests should be. 您还需要考虑集成测试的高级程度。 For instance, does your service call out to other service (including actors) within the same cluster using fabric transport (the default communication model) that you want to include in your integration test? 例如,您的服务是否使用要在集成测试中包含的结构传输(默认通信模型)调用同一集群中的其他服务(包括演员)? Do you need to ensure that state is persisted across multiple activations of the same service partition? 您是否需要确保在同一服务分区的多次激活中持久保存状态?

First you need to get rid of all hard dependencies to FabricRuntime (to things with dependencies to it) and also static support classes in your code: 首先,您需要摆脱FabricRuntime的所有硬依赖(对于依赖于它的东西)以及代码中的静态支持类:

Service/Actor proxy 服务/演员代理

Don't use the static ServiceProxy.Create<..)(..)> when calling other services, instead make sure your Service accepts an instance of IServiceProxyFactory in the constructor and use that instance to create proxies to services your service calls. 调用其他服务时,请不要使用静态ServiceProxy.Create<..)(..)> ,而是确保您的服务在构造函数中接受IServiceProxyFactory的实例,并使用该实例为服务调用的服务创建代理。 Same goes for ActorProxy.Create<..>(..) , replace this with an instance of IActorProxyFactory . ActorProxy.Create<..>(..) ,将其替换为IActorProxyFactory的实例。 In your program.cs where the service is constructed, give the service new ServiceProxyFactory() and new ActorProxyFactory() . 在构造服务的program.cs ,为服务提供new ServiceProxyFactory()new ActorProxyFactory() That's the easy part, now you need to mock those so that your integration tests can actually create some form of proxy for downstream services. 这是最简单的部分,现在您需要模拟这些,以便您的集成测试实际上可以为下游服务创建某种形式的代理。 You will also need to create some form of container (like a mock FabricRuntime) that holds instances of called services and actors. 您还需要创建某种形式的容器(如模拟FabricRuntime),它包含被调用服务和actor的实例。 It also gets tricky if you wan't to test that the RunAsync method of your service performs some function. 如果您不想测试服务的RunAsync方法执行某些功能,那么它也会变得棘手。 Beware of creating this static though if you want to run it in a test runner, you don't want different tests to get mixed up in the same container. 请注意创建此静态,但如果要在测试运行器中运行它,则不希望在同一容器中混合使用不同的测试。

Service context 服务背景

You need to mock your StatefulServiceContext well and how your Service is created. 您需要很好地模拟StatefulServiceContext以及如何创建服务。 Your Service constructors need to accept an instance of StatefulServiceContext to pass along to the base class, so you are free to supply your own mocked instances of context there when you create the service. 您的服务构造函数需要接受StatefulServiceContext的实例以传递给基类,因此您可以在创建服务时自由地提供您自己的模拟上下文实例。

public StatefulService(StatefulServiceContext serviceContext)
    : base(serviceContext) {}

Service settings and activation context 服务设置和激活上下文

You also need to see if your service implementation tries to read ICodePackageActivationContext or any of the settings from the Service manifest (like shown in this SO answer Where do you set and access run-time configuration parameters per environment for service fabric? ). 您还需要查看您的服务实现是否尝试读取ICodePackageActivationContext或服务清单中的任何设置(如此答案中所示)您在哪里设置和访问服务结构的每个环境的运行时配置参数? )。 In that case you need to replace it with your own mockable version and you need to inject that in the constructor as well. 在这种情况下,您需要将其替换为您自己的可模拟版本,并且您还需要在构造函数中注入它。 What you find in most samples is a call to the service context, like this: 您在大多数示例中找到的是对服务上下文的调用,如下所示:

this.Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");

If you do it this way in your service then you need make sure you have a mock of StatefulServiceContext as well and how your Service is created. 如果您在服务中以这种方式执行此操作,那么您需要确保模拟StatefulServiceContext以及如何创建服务。 When you register your service with the runtime in Program.Main() then you get and instance of StatefulServiceContext in the register call: 当您在Program.Main()使用运行时注册服务时,您将在注册调用中获得StatefulServiceContext实例:

ServiceRuntime.RegisterServiceAsync("ServiceType", 
    context => new Service(context)).GetAwaiter().GetResult();

State

In order to mock state and get it to behave similar to what it will when running in a real cluster you need to mock the underlying handler for reliable state: IReliableStateManagerReplica and you need to add an overloaded constructor to your services that accepts an instance of that and sends it to the base: 为了模拟状态并使其行为类似于在真实集群中运行时的行为,您需要模拟可靠状态的基础处理程序: IReliableStateManagerReplica并且您需要将重载的构造函数添加到接受其实例的服务中并将其发送到基地:

public StatefulService(StatefulServiceContext serviceContext, IReliableStateManagerReplica reliableStateManagerReplica)
    : base(serviceContext, reliableStateManagerReplica) {}

For actors its IActorStateProvider you need to mock if you want to handle state in your integration tests. 对于actor IActorStateProvider ,如果要在集成测试中处理状态,则需要进行模拟。

Summary 摘要

Depending on how advanced you want your integration tests to be and how close to the real execution model you want it to be, you may end up having to mock and replace a large number of classes/interfaces. 根据您希望集成测试的高级程度以及您希望它与实际执行模型的接近程度,您可能最终必须模拟并替换大量的类/接口。 The Web reference application sample https://github.com/Azure-Samples/service-fabric-dotnet-web-reference-app has some implementation of Mocks for required classes, also https://github.com/loekd/ServiceFabric.Mocks contains Mocks for testing, although you might need to alter the code if you really want to run integration tests and not just unit tests. Web参考应用程序示例 https://github.com/Azure-Samples/service-fabric-dotnet-web-reference-app有一些针对所需类的Mocks实现,还有https://github.com/loekd/ServiceFabric。模拟包含用于测试的模拟,但如果您真的想要运行集成测试而不仅仅是单元测试,则可能需要更改代码。

使用常规api对无状态web api进行集成测试没有区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM