Moq - 为简单的工厂创建的DTO界面创建内联假

Nig*_*888 0 c# nunit unit-testing moq

我有一个简单的抽象工厂,返回一个简单的类型.基本上,它只是用数据填充类型并返回它,类似于DTO.

public interface IPagingInstructionFactory
{
    IPagingInstruction Create(int skip, int take, IProvider provider);
}

public interface IPagingInstruction
{
    int Skip { get; }
    int Take { get; }
    IProvider Provider { get; }
}
Run Code Online (Sandbox Code Playgroud)

我现在想要创建一个模拟工厂,它基本上与真实工厂做同样的事情 - 它从Create()方法传递参数并从IPagingInstruction实例的属性返回它们.

这是一个有效的例子:

var pagingInstructionFactory = new Mock<IPagingInstructionFactory>();
pagingInstructionFactory
    .Setup(x => x.Create(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<IProvider>()))
    .Returns((int skip, int take, IProvider provider) => 
        new FakePagingInstruction(skip, take, provider));


public class FakePagingInstruction
    : IPagingInstruction
{
    public FakePagingInstruction(
        int skip,
        int take,
        IProvider provider
        )
    {
        if (provider == null)
            throw new ArgumentNullException("provider");

        this.skip = skip;
        this.take = take;
        this.provider = provider;
    }
    private readonly int skip;
    private readonly int take;
    private readonly IProvider provider;

    public int Skip
    {
        get { return this.skip; }
    }

    public int Take
    {
        get { return this.take; }
    }

    public IProvider Provider
    {
        get { return this.provider; }
    }
}   
Run Code Online (Sandbox Code Playgroud)

在我看来,Moq应该能够创建一个假的对象,可以返回所有3个属性,而不是使用手工编码的假.但是,我似乎无法弄清楚如何使它返回作为参数传递到假工厂的值.

可以这样做,还是每次我需要这样做时都需要使用手工编码的假货?

dca*_*tro 5

你的意思是这样的?

var pagingInstructionFactory = new Mock<IPagingInstructionFactory>();
this.pagingInstructionFactory
    .Setup(x => x.Create(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<IProvider>()))
    .Returns((int skip, int take, IProvider provider) => 
    {
        var instruction = new Mock<IPagingInstruction>();
        instruction.Setup(i => i.Skip).Returns(skip);
        instruction.Setup(i => i.Take).Returns(take);
        instruction.Setup(i => i.Provider).Returns(provider);

        return instruction.Object;
    });
Run Code Online (Sandbox Code Playgroud)

这将设置Create为每次调用时返回一条新指令.如果要返回相同的实例,或者如果要稍后对指令执行某些断言,则必须将声明移出委托.