用Moq替换Setup的值

时间:2018-02-05 14:54:04

标签: c# entity-framework entity-framework-6 moq

我嘲笑DbContext及其DbSet s as described here

我想创建一个实用程序方法来创建我的模拟DbContext,默认情况下会设置每个上下文的DbSet以返回一个空列表(否则每当我尝试查询其中一个DbSet时,我都会收到有关空引用的错误。然后在单元测试中我想要某个DbSet中的非空数据,我想再次在Setup上调用DbSet来提供比我想要返回的值。代码如下。

我在单元测试中做到这一点似乎有效,但我无法找到有关Moq如何在同一属性上处理Setup两次调用的任何内容。这样做好,还是会产生意想不到的副作用?使用调试器,我查看context.Setups,并在同一属性上第二次调用Setup,向Setups添加第二个对象,而不是覆盖第一个,这让我担心。

[TestClass]
public class MyTests
{
    // Creates a new Mock<MyContext> and calls Setup on each property so
    // that they all return empty lists
    private Mock<MyContext> CreateContext()
    {
        Mock<MyContext> context = new Mock<MyContext>();

        // CreateMockDbSet is a utility method which creates a Mock<DbSet<TEntity>>
        // as described in the MSDN article listed above
        context.Setup(e => e.Customers).Returns(CreateMockDbSet<Customer>().Object);
        context.Setup(e => e.Orders).Returns(CreateMockDbSet<Order>().Object);

        return context;
    }

    [TestMethod]
    public void MyTest()
    {
        // By default, context.Customers and context.Orders will both return
        // empty DbSets
        Mock<MyContext> context = CreateContext();

        List<Order> orders = new List<Order>
        {
            new Order { Id = 1 },
            new Order { Id = 2 },
            new Order { Id = 3 }
        };

        // CreateMockDbSet creates a Mock<DbSet<Order>> which returns the orders
        // in 'orders'.  What does Moq do when I call Setup again on 'Orders'?
        context.Setup(e => e.Orders).Returns(CreateMockDbSet(orders).Object);

        // ... Do test ...
    }
}

https://msdn.microsoft.com/en-us/library/dn314429(v=vs.113).aspx

1 个答案:

答案 0 :(得分:1)

如果在方法上创建后续设置并且它是非条件的(对参数没有约束),那么它将删除该方法的所有先前设置。

如果您没有接受参数的方法,那么您显然无法对它们添加任何约束,因此您的后续设置将只替换之前的设置。

有关源代码的说明,请参阅this answer