Тестирование устройства и зависимостей

Я не могу проверить надежный сервис/актер, просто называя его конструктором, а затем проверять его методы. 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.