测试 FabricClient 对象

Testing FabricClient object

我需要测试一个依赖于对象 System.Fabric.FabricClient 的方法。具体来说,该方法从该对象读取分区列表:

ServicePartitionList partitions = await this.fabricClient.QueryManager.GetPartitionListAsync(serviceName);

然后,该方法遍历列表并获取每个分区的数据。

foreach (Partition partition in partitions)
{
    // ... code to verify
    LowKey = ((Int64RangePartitionInformation)partition.PartitionInformation).LowKey;
    PartitionId = partition.PartitionInformation.Id;
    Health = partition.HealthState;
    // ... code to verify
}

我正在为模拟接口使用最小起订量库,但我不能将其用于此具体 class。

我试过用接口包装 FabricClient,但所有涉及的对象都是抽象的或密封的,我无法实例化这些对象。

我也尝试过使用 ServiceFabric.Mocks 但我没有运气。我认为 FabricClient 需要服务 运行 工作。

总而言之,我需要的是当我尝试读取分区列表时 FabricClient 对象不会向我抛出任何错误,并且如果可能的话,从中获取假值。

编辑:

最后,我从 FabricClient 对象中包装了我需要的所有对象,并通过接口公开它们:

public interface IFabricClientWrapper
{
    Task<ServicePartitionListWrapper> GetPartitionListAsync(Uri serviceName);
}

public class FabricClientWrapper : IFabricClientWrapper
{
    private FabricClient fabricClient;

    public FabricClientWrapper()
    {
        fabricClient = new FabricClient();
    }

    public async Task<ServicePartitionListWrapper> GetPartitionListAsync(Uri serviceName)
    {
        var list = new ServicePartitionListWrapper();
        var partitionList = await fabricClient.QueryManager.GetPartitionListAsync(serviceName);
        foreach (var partition in partitionList)
        {
            PartitionWrapper partitionWrapper = new PartitionWrapper();
            partitionWrapper.Id = partition.PartitionInformation.Id;
            partitionWrapper.HealthState = partition.HealthState;
            partitionWrapper.LowKey = ((Int64RangePartitionInformation)partition.PartitionInformation).LowKey;
            partitionWrapper.HighKey = ((Int64RangePartitionInformation)partition.PartitionInformation).HighKey;
            list.Add(partitionWrapper);
        }
        return list;
    }
}

public class ServicePartitionListWrapper : List<PartitionWrapper> { }

public class PartitionWrapper
{
    public Guid Id { get; set; }
    public HealthState HealthState { get; set; }
    public long LowKey { get; set; }
    public long HighKey { get; set; }
}

FabricClient 与集群运行时紧密耦合。

你可以在这里使用一个抽象层。 不要直接调用 QueryManager,而是将其包装在另一个 class 中,类似于:

public class PartitionInfoProvider : IPartitionInfoProvider 
{
   private FabricClient fabricClient;

   public PartitionInfoProvider(FabricClient fabricClient)
   {
      this.fabricClient = fabricClient;
   }

   public Task<ServicePartitionList> GetPartitions()
   {
      return this.fabricClient.QueryManager.GetPartitionListAsync(serviceName);          
   }
}

使用接口声明将实现传递给服务构造函数。

然后,当 运行 您的测试时,您可以模拟提供此提供程序的模拟实现。