Как мы можем выполнить интеграционный тест на сервисной фабрике (служба без сохранения состояния)?
Я хотел бы выполнить интеграцию службы без сохранения состояния в сервисной структуре. Пожалуйста, помогите мне в этом. Я создал службу без сохранения состояния, как C# web api.
2 ответа
Чтобы выполнить интеграционные тесты на вашем Надежном Сервисе, существует ряд зависимостей, которые вы должны смоделировать и позаботиться. Вы не сможете проверить все ситуации или поведение вашего сервиса таким образом, как FabricRuntime
хосты и сервисы сложно копировать (без написания собственного эквивалента FabricRuntime). Стоит также отметить, что бегать нельзя FabricRuntime
без кластера (включая кластер локальной разработки).
Вы также должны подумать о том, насколько продвинутыми должны быть ваши интеграционные тесты. Например, обращается ли ваша служба к другой службе (включая участников) в том же кластере, используя матричный транспорт (модель связи по умолчанию), который вы хотите включить в свой интеграционный тест? Нужно ли гарантировать, что состояние сохраняется при нескольких активациях одного и того же служебного раздела?
Сначала вам нужно избавиться от всех жестких зависимостей FabricRuntime
(для вещей с зависимостями от него), а также статические классы поддержки в вашем коде:
Сервис / Актер прокси
Не используйте статический ServiceProxy.Create<..)(..)>
при вызове других сервисов, убедитесь, что ваш сервис принимает экземпляр IServiceProxyFactory
в конструкторе и используйте этот экземпляр для создания прокси для сервисов ваших сервисных вызовов. То же самое касается ActorProxy.Create<..>(..)
замените это экземпляром IActorProxyFactory
, В вашем program.cs
где сервис построен, дай сервис new ServiceProxyFactory()
а также new ActorProxyFactory()
, Это простая часть, теперь вам нужно смоделировать их, чтобы ваши интеграционные тесты действительно могли создать какую-то форму прокси для последующих сервисов. Вам также нужно будет создать некоторую форму контейнера (например, фиктивный FabricRuntime), который будет содержать экземпляры вызываемых сервисов и актеров. Это также сложно, если вы не хотите проверить, что RunAsync
Метод вашего сервиса выполняет какую-то функцию. Остерегайтесь создания этой статики, хотя, если вы хотите запустить ее в тестовом средстве, вам не нужно, чтобы разные тесты смешивались в одном и том же контейнере.
Сервисный контекст
Вы должны издеваться над StatefulServiceContext
ну и как твоя служба создана. Ваши конструкторы службы должны принять экземпляр StatefulServiceContext
перейти к базовому классу, так что вы можете свободно указывать свои собственные макетные экземпляры контекста при создании сервиса.
public StatefulService(StatefulServiceContext serviceContext)
: base(serviceContext) {}
Настройки сервиса и контекст активации
Вы также должны увидеть, пытается ли ваша реализация службы прочитать ICodePackageActivationContext
или любой из параметров из манифеста службы (как показано в этом ответе SO Где вы устанавливаете и получаете доступ к параметрам конфигурации времени выполнения для каждой среды для сервисной фабрики?). В этом случае вам нужно заменить его на вашу собственную версию, и вам также нужно добавить это в конструктор. В большинстве примеров вы обнаружите обращение к контексту службы, например:
this.Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
Если вы делаете это в своем служении, то вам нужно убедиться, что у вас есть StatefulServiceContext
а также и как создается ваш Сервис. Когда вы регистрируете свой сервис во время выполнения в Program.Main()
тогда вы получите и экземпляр StatefulServiceContext
в реестре звонков:
ServiceRuntime.RegisterServiceAsync("ServiceType",
context => new Service(context)).GetAwaiter().GetResult();
государственный
Чтобы смоделировать состояние и заставить его вести себя подобно тому, как оно будет работать при работе в реальном кластере, вам нужно смоделировать основной обработчик для надежного состояния: IReliableStateManagerReplica
и вам нужно добавить перегруженный конструктор в ваши службы, который принимает экземпляр этого и отправляет его в базу:
public StatefulService(StatefulServiceContext serviceContext, IReliableStateManagerReplica reliableStateManagerReplica)
: base(serviceContext, reliableStateManagerReplica) {}
Для актеров это IActorStateProvider
вам нужно издеваться, если вы хотите обрабатывать состояние в ваших интеграционных тестах.
Резюме
В зависимости от того, насколько вы хотите, чтобы ваши интеграционные тесты были, и насколько вы хотите, чтобы реальная модель исполнения была такой, вам может понадобиться смоделировать и заменить большое количество классов / интерфейсов. Пример веб-справочного приложения https://github.com/Azure-Samples/service-fabric-dotnet-web-reference-app содержит некоторую реализацию Mocks для обязательных классов, а также https://github.com/loekd/ServiceFabric.Mocks содержит Mocks для тестирования, хотя вам может потребоваться изменить код, если вы действительно хотите запускать интеграционные тесты, а не только модульные тесты.
Нет разницы в ваших интеграционных тестах на API без состояния с обычным API.