测试FabricClient对象

时间:2018-03-15 16:49:18

标签: unit-testing testing moq azure-service-fabric

我需要测试一个依赖于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
}

我使用moq库进行模拟接口,但是我不能在这个具体的类中使用它。

我尝试使用接口包装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; }
}

1 个答案:

答案 0 :(得分:2)

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

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

public class PartitionInfoProvider : IPartitionInfoProvider 
{
   private FabricClient fabricClient;

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

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

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

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