我需要测试一个依赖于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; }
}
答案 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构造函数。
然后,您可以在运行测试时模拟提供此提供程序的模拟实现。