【问题标题】:How to unit test Service Fabric Actor with State如何使用 State 对 Service Fabric Actor 进行单元测试
【发布时间】:2016-06-02 20:56:11
【问题描述】:

我已经开始为有状态的新演员编写单元测试。状态在激活 Actor 时由 Service Fabric 调用的 OnActivateAsync 方法中初始化。

在进行单元测试时,我自己创建了 Actor,并且由于该方法受到保护,我无法从我的单元测试中访问自己来调用此方法。

我想知道这种测试的常用方法。我可以模拟 Actor 并模拟状态,但是对于我要测试的代码调用原始代码。我想知道是否还有另一种我没有遇到过的方法。

另一种方法是将状态初始化移动到其他地方,如公共方法或构造函数中,但 Actor 的模板在那里有代码,因此它可能是最佳实践。

【问题讨论】:

    标签: unit-testing azure-service-fabric


    【解决方案1】:

    我明白这并不理想,但您可以使用反射来调用OnActivateAsync() 方法。

    例如,

    var method = typeof(ActorBase).GetMethod("OnActivateAsync", BindingFlags.Instance | BindingFlags.NonPublic);
    await (Task)method.Invoke(actor, null);
    

    这样您将测试您想要测试的实际方法,也不会公开您不想公开的方法。

    您可能会发现将参与者的创建和对 OnActivateAsync() 的手动调用分组到一个方法中很有用,以便在您的测试套件中使用它并模仿原始的 Service Fabric 行为。

    【讨论】:

    • 除了 resharper 不喜欢我的带有异步标志的测试之外,(不知道为什么)它起作用了——这正是我所追求的。我经常忘记反射以及它可以做什么。
    【解决方案2】:

    我喜欢在actor上使用InternalsVisibleTo属性和一个内部方法,它调用OnActivateAsync方法。

    在目标 Actor 项目中,AssemblyInfo.cs 添加如下一行:

    [assembly: InternalsVisibleTo("MyActor.Test")]
    

    其中“MyActor.Test”是您要授予内部成员访问权限的测试项目的名称。

    在目标 Actor 类中添加一个类似这样的方法:

    internal Task InvokeOnActivateAsync()
    {
        return OnActivateAsync();
    }
    

    这样您就可以从您的测试项目中调用 OnActivateAsync 方法,如下所示:

    var actor = CreateNewActor(id);
    actor.InvokeOnActivateAsync()
    

    【讨论】:

      【解决方案3】:

      使用最新版本的 ServiceFabric.Mocks NuGet 包。它包含调用 OnActivateAsync 保护方法的特殊扩展和用于 ServiceFabric 单元测试的整个工具集。

              var svc = MockActorServiceFactory.CreateActorServiceForActor<MyActor>();
              var actor = svc.Activate(new ActorId(Guid.NewGuid()));
              actor.InvokeOnActivateAsync().Wait();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-14
        • 1970-01-01
        • 2013-05-23
        • 1970-01-01
        • 1970-01-01
        • 2021-03-27
        • 2016-03-11
        • 2018-01-11
        相关资源
        最近更新 更多