Service Fabric Unit Testing and Dependency Injection

前端 未结 2 1036
独厮守ぢ
独厮守ぢ 2021-02-12 22:43

I can\'t test a Reliable Service/Actor by just calling it\'s constructor and then test it\'s methods. var testService = new SomeService(); throws a NullReferenceExc

相关标签:
2条回答
  • 2021-02-12 23:08

    For mocking the state manager in Reliable Actors, you can do something like this:

    private readonly IActorStateManager _stateManager;
    
    public MyActor(IActorStateManager stateManager = null)
    {
        _stateManager = stateManager ?? this.StateManager;
    }
    

    Actually, the StateManager isn't yet initialized at this time. We can get it when OnActivateAsync is called:

    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;
        }
    }
    

    Just make sure to always use _stateManager in the rest of the code instead of this.StateManager.

    0 讨论(0)
  • 2021-02-12 23:11

    Actually you can test Reliable Services and Actors the same way you'd test any other class in .NET! They're only special in that they use certain hooks into the underlying platform, but other than that you can instantiate your service or actor class normally and call methods on it.

    Currently, Reliable Services are a little easier to unit test because the primary hook into the platform, the State Manager, is an interface that's pluggable through the constructor.

    For example, your service class might look like this:

    EDIT: Updated with the GA release API (2.0.135)

    class MyService : StatefulService
    {
      public MyService (StatefulServiceContext context, IReliableStateManager stateManager)
          :base (context, stateManager)
      {
      }
    
      public void MyMethod()
      {
        // do stuff..
      }
    }
    

    Then you can test your service class like so:

    [TestMethod]
    public TestMyMethod()
    {
      MockReliableStateManager stateManager = new MockReliableStateManager();
      MyService target = new MyService(stateManager);
    
      target.MyMethod();
      // validate results and all that good stuff
    }
    

    We have a full working example of actual services with lots of dependencies being unit tested available on GitHub: https://github.com/Azure-Samples/service-fabric-dotnet-management-party-cluster

    This example has IReliableStateManager and IReliableDictionary mocks as well that you can use as a starting point for your own unit tests.

    0 讨论(0)
提交回复
热议问题