简体   繁体   English

具有多个签名的 Moq 规范模式接口实现

[英]Moq Specification Pattern Interface implemenation with multiple signatures

I'm trying to setup two different mocked objects based on the inputs supplied.我正在尝试根据提供的输入设置两个不同的模拟对象。

The generic Interface definitions is as follows:通用接口定义如下:

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; }
}

Then an implementing class which has three methods and derives from an intermediary base class.然后是一个实现 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");
    }
}

Basic mocking of this is a simple as:基本的 mocking 这很简单:

mock.Setup(m => m.ListAsync(It.IsAny<ISpecification<WindFarm>>()))
            .Returns(() =>
            {
                var windFarms = new List<WindFarm>
                {
                    testWindFarm1
                };

                return Task.FromResult((IReadOnlyList<WindFarm>)windFarms);
            });

Which is OK, as long as I don't care what get returns and abstracts away the details.没关系,只要我不在乎得到什么回报并抽象出细节。 However, I do now need to care about this.但是,我现在确实需要关心这一点。

How do I modify the moq It.IsAny<ISpecification<WindFarm>>() so that I can differentiate between如何修改It.IsAny<ISpecification<WindFarm>>()以便区分

public WindFarmsSpecification()

and

public WindFarmsSpecification(string name)

It is not explicitly possible to know which constructor was used.无法明确知道使用了哪个构造函数。 But it can be implied based on what is populated in the parameter according to what was shown in the example constructors.但它可以根据示例构造函数中显示的内容基于参数中填充的内容来暗示。

Capture the passed parameter and use as needed捕获传递的参数并根据需要使用

For example例如

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;
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM