Тестирование устройства и зависимостей
Я не могу проверить надежный сервис/актер, просто называя его конструктором, а затем проверять его методы. var testService = new SomeService();
генерирует исключение NullReferenceException. Итак, что я могу сделать с развернутым сервисом.
Я понимаю, что развернутые SF Reliable Services/Actors не являются стандартными .NET-классами, а модульное тестирование развернутой S/A может быть странной идеей.
В любом случае, я пытаюсь попробовать.
Например. Я только что развернул службу, а в тесте я создал объект Proxy и добавил элемент во входную очередь службы. Затем мне нужно утверждать, что количество входных очередей = 1. И оно работает, если я только что развернул службу, и никакие другие Клиенты/Сервисы/Актеры не использовали эту входную очередь. Но в следующий раз этот тест не удастся решить эту проблему. Мне нужно, чтобы Служба перестала работать с другими потребителями, опустила очередь и проверила ее. Для этого я могу создать некоторое свойство TestMode и некоторые методы, такие как PropareoForTests/TestingCompleted и вызвать их из тестового клиента до и после тестирования.
Это плохая идея, чтобы сделать это так. Возможно, есть ли какие-то рекомендации для модульного тестирования SF? Спасибо.
UPDATE:
При исследовании Пример веб-справочника веб-сайта службы технической поддержки Я нашел эту строку TODO:
/// TODO: Temporary property-injection for an IServiceProxyWrapper until constructor injection is available.
Означает ли это, что SF Services улучшит поддержку DI? Как насчет актеров?
Ответы
Ответ 1
На самом деле вы можете тестировать надежные сервисы и актеры таким же образом, как и в других классах .NET! Они только особенные в том, что они используют определенные перехватчики в базовой платформе, но кроме этого вы можете создать экземпляр своего класса обслуживания или актера нормально и вызвать методы на нем.
В настоящее время надежные службы немного легче unit test, потому что основной крючок в платформе, State Manager, является интерфейсом, который подключается через конструктор.
Например, ваш класс службы может выглядеть следующим образом:
EDIT: Обновлен с помощью API выпуска GA (2.0.135)
class MyService : StatefulService
{
public MyService (StatefulServiceContext context, IReliableStateManager stateManager)
:base (context, stateManager)
{
}
public void MyMethod()
{
// do stuff..
}
}
Затем вы можете проверить свой класс обслуживания следующим образом:
[TestMethod]
public TestMyMethod()
{
MockReliableStateManager stateManager = new MockReliableStateManager();
MyService target = new MyService(stateManager);
target.MyMethod();
// validate results and all that good stuff
}
У нас есть полный рабочий пример фактических сервисов с большим количеством зависимостей, которые могут быть проверены модулем на GitHub: https://github.com/Azure-Samples/service-fabric-dotnet-management-party-cluster
В этом примере есть IReliableStateManager и IReliableDictionary mocks, которые вы можете использовать в качестве отправной точки для своих собственных модульных тестов.
Ответ 2
Чтобы издеваться над менеджером штата в Reliable Actors, вы можете сделать что-то вроде этого:
private readonly IActorStateManager _stateManager;
public MyActor(IActorStateManager stateManager = null)
{
_stateManager = stateManager ?? this.StateManager;
}
Забастовкa >
На самом деле, 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;
}
}
Просто убедитесь, что всегда используйте _stateManager
в остальной части кода вместо this.StateManager
.