测试服务结构参与者:单位与整合

时间:2016-09-28 14:36:01

标签: unit-testing azure-service-fabric

目前关于单元测试SF演员的示例很少,我现在正试图了解测试框架提供的功能SF演员(状态,提醒,计时器等)的正确/最佳方法。

我的大脑的一部分(我通常的工作方式)告诉我单独测试演员内部的所有内容并集成测试演员的界限。但是我感觉我正在反对演员框架来做这件事。

例如,对于状态管理,我感觉就像我想要执行下面的'New'方法中描述的那样并抽象掉stateManager:

public class MyActor : Actor, IMyActor
{
    private readonly IWidgetStore _widgetStore; 
    private readonly ISomeLogic _someLogic; 

    public MyActor(service, id, widgetStore, someLogic) : base(service, id){
         _widgetStore = widgetStore;
    }

    public Task New(int x, int y){
         var result = _someLogic.Calculate(x,y);
         _widgetStore.Upsert(result); 
    }

    public Task Old(int x, int y){
         var result = _someLogic.Calculate(x,y);
         this.actorStateManager.AddOrUpdateStateAsync("widget_state", result, (s, s1) => result).Wait(); 
    }
}

public class WidgetStore : IWidgetStore
{
     private readonly IActorStateManager _actorStateManager;

     public WidgetStore(IActorStateManager actorStateManager)
     {
          _actorStateManager = actorStateManager;
     } 
     public Task Upsert(string value)
     {
          _actorStateManager.AddOrUpdateStateAsync("widget_state", value, (s, s1) => value).Wait();
     }
}

这样做是对的,但我需要一个保证,我的 widgetStore 单元实际上正常工作并且状态正在持续存在。

两个选项

  1. 编写 widgetStore 单元测试,以根据StateManager方法验证调用。显然这并不是实际上调用真正的实现,但是'verify'是否足够?我觉得我应该能够依靠框架来实际执行它应该做的事情... 作为加法运算符的使用者,你不会对加法运算符编写测试来证明1 + 1你会吗?
  2. 编写一套测试,涵盖与真实的actor框架集成(运行时在本地集群上运行)。我将针对真正的stateManager进行集成,并使用ActorProxy有效地测试Actors行为的黑盒子。如果行为测试通过,那么我必须正确存储状态?这感觉更好,但这不是一次验收测试吗?
  3. 当我起草这个问题时,我觉得我应该采取一种方法来测试Actors,这通常与我过去对我的服务进行单元测试的方式背道而驰。

    我觉得我应该拥抱演员框架&运行时作为一个整体单元,并从行为角度进行测试,如选项2中所述。

    我现在正在向您(SF社区)寻求关于此的讨论和建议。

    修改

    如果我要抽象 widgetStore 单元后面的状态管理器,那么在构建Actor之前没有友好的方式来获取stateManager,所以现在我必须做这样的事情(在ActorRuntime中)。 RegisterActorAsync方法)...

    Func<ActorService, ActorId, ActorBase> actorFactory = (service, id) =>
    {
          var widgetStore = new WidgetStore();
          var someLogic = new SomeLogic();
    
          var actor = new MyActor(service, id, widgetStore, someLogic);
    
          widgetStore.Inject(actor.StateManager);
    
          return actor;
    };
    

    由于我现在不得不在widgetStore上公开一个注入stateManager的方法,因为你无法在actor构建之前进入stateManager。

0 个答案:

没有答案