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

时间:2014-08-20 19:18:19

标签: c# unit-testing nunit 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; }
}

我现在想要创建一个模拟工厂,它基本上与真实工厂做同样的事情 - 它从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; }
    }
}   

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

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

1 个答案:

答案 0 :(得分: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;
    });

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