具有多个签名的 Moq 规范模式接口实现
Moq Specification Pattern Interface implemenation with multiple signatures
我正在尝试根据提供的输入设置两个不同的模拟对象。
泛型接口定义如下:
public interface ISpecification<T>
{
Expression<Func<T, bool>> Criteria { get; }
List<Expression<Func<T, object>>> Includes { get; }
List<string> IncludeStrings { get; }
Expression<Func<T, object>> OrderBy { get; }
Expression<Func<T, object>> OrderByDescending { get; }
int Take { get; }
int Skip { get; }
bool IsPagingEnabled { get; }
}
然后是一个实现 class,它具有三个方法并派生自中间基础 class。
public sealed class WindFarmsSpecification : BaseSpecification<WindFarm>
{
public WindFarmsSpecification()
: base(null)
{
this.AddInclude("Submissions");
this.ApplyOrderBy(s => s.Name);
}
public WindFarmsSpecification(string name)
: base(s => s.Name.Contains(name))
{
this.AddInclude("Submissions");
this.ApplyOrderBy(s => s.Name);
}
public WindFarmsSpecification(Guid guidId)
: base(s => s.GuidId == guidId)
{
this.AddInclude("Submissions");
}
}
对此的基本模拟很简单:
mock.Setup(m => m.ListAsync(It.IsAny<ISpecification<WindFarm>>()))
.Returns(() =>
{
var windFarms = new List<WindFarm>
{
testWindFarm1
};
return Task.FromResult((IReadOnlyList<WindFarm>)windFarms);
});
没关系,只要我不在乎得到什么 returns 并抽象掉细节。但是,我现在确实需要关心这个。
如何修改最小起订量 It.IsAny<ISpecification<WindFarm>>()
以便区分
public WindFarmsSpecification()
和
public WindFarmsSpecification(string name)
无法明确知道使用了哪个构造函数。但是可以根据示例构造函数中显示的内容,根据参数中填充的内容来暗示它。
捕获传递的参数并根据需要使用
例如
mock
.Setup(_ => _.ListAsync(It.IsAny<ISpecification<WindFarm>>()))
.ReturnsAsync((ISpecification<WindFarm> spec) => {
//access passed argument
var criteria = spec.Criteria;
//use expression to filter a mock list
var result = somelist.Where(criteria).OrderBy(spec.OrderBy).ToList();
return (IReadOnlyList<WindFarm>)result;
});
我正在尝试根据提供的输入设置两个不同的模拟对象。
泛型接口定义如下:
public interface ISpecification<T>
{
Expression<Func<T, bool>> Criteria { get; }
List<Expression<Func<T, object>>> Includes { get; }
List<string> IncludeStrings { get; }
Expression<Func<T, object>> OrderBy { get; }
Expression<Func<T, object>> OrderByDescending { get; }
int Take { get; }
int Skip { get; }
bool IsPagingEnabled { get; }
}
然后是一个实现 class,它具有三个方法并派生自中间基础 class。
public sealed class WindFarmsSpecification : BaseSpecification<WindFarm>
{
public WindFarmsSpecification()
: base(null)
{
this.AddInclude("Submissions");
this.ApplyOrderBy(s => s.Name);
}
public WindFarmsSpecification(string name)
: base(s => s.Name.Contains(name))
{
this.AddInclude("Submissions");
this.ApplyOrderBy(s => s.Name);
}
public WindFarmsSpecification(Guid guidId)
: base(s => s.GuidId == guidId)
{
this.AddInclude("Submissions");
}
}
对此的基本模拟很简单:
mock.Setup(m => m.ListAsync(It.IsAny<ISpecification<WindFarm>>()))
.Returns(() =>
{
var windFarms = new List<WindFarm>
{
testWindFarm1
};
return Task.FromResult((IReadOnlyList<WindFarm>)windFarms);
});
没关系,只要我不在乎得到什么 returns 并抽象掉细节。但是,我现在确实需要关心这个。
如何修改最小起订量 It.IsAny<ISpecification<WindFarm>>()
以便区分
public WindFarmsSpecification()
和
public WindFarmsSpecification(string name)
无法明确知道使用了哪个构造函数。但是可以根据示例构造函数中显示的内容,根据参数中填充的内容来暗示它。
捕获传递的参数并根据需要使用
例如
mock
.Setup(_ => _.ListAsync(It.IsAny<ISpecification<WindFarm>>()))
.ReturnsAsync((ISpecification<WindFarm> spec) => {
//access passed argument
var criteria = spec.Criteria;
//use expression to filter a mock list
var result = somelist.Where(criteria).OrderBy(spec.OrderBy).ToList();
return (IReadOnlyList<WindFarm>)result;
});