Moq - 提取Mock DataSet&上下文到单独的类

时间:2014-07-11 15:19:53

标签: c# entity-framework unit-testing moq

我有一个单元测试,用于验证函数是否只向一个Entity Framework数据集添加了一条记录,如下所示:

var internals = new Mock<DbSet<InternalTransaction>>();
internals.Setup(q => q.Create()).Returns(new InternalTransaction());

var mockDC = new Mock<IDataContext>();
mockDC.Setup(q => q.InternalTransactions).Returns(internals.Object);

// Removed:  set up some data for my test
mockDC.Object.DoSomeFunction(data);

internals.Verify(e => e.Add(It.IsAny<InternalTransaction>()), Times.Once());

由于我对此上下文进行了大量测试,因此我尝试将模拟内容提取到单独的类中,如下所示:

public static class DataContext_Creators
{
    public static Mock<IDataContext> CreateMockContext()
    {
        var internals = CreateMockDataSet<InternalTransaction>();
        var externals = CreateMockDataSet<ExternalTransaction>();

        var mockDC = new Mock<IDataContext>();

        mockDC.Setup(q => q.InternalTransactions).Returns(internals.Object);
        mockDC.Setup(q => q.ExternalTransactions).Returns(externals.Object);

        return mockDC;
    }

    private static Mock<DbSet<T>> CreateMockDataSet<T>() where T : class, new ()
    {
        var mockDataSet = new Mock<DbSet<T>>();
        mockDataSet.Setup(q => q.Create()).Returns(new T());
        // some other stuff, Provider, GetEnumerator, etc
        return mockDataSet;
    }
}

...并将我的测试更改为:

mockContext = Common.DataContext_Creators.CreateMockContext();
context = mockContext.Object;

// Removed:  set up some data for my test
context.Object.DoSomeFunction(data);

//internals.Verify(e => e.Add(It.IsAny<InternalTransaction>()), Times.Once());

但是现在我再也无法访问“内部”了,我该如何处理.Verify()语句? context.InternalTransactions不起作用,因为它返回“internals.Object”(我正在测试的方法需要它才能工作)。

2 个答案:

答案 0 :(得分:1)

通过使用Mock.Get()方法,您可以再次从该对象中重新获得它的Mock对象。看一下例子:

public class Entity
{
    public virtual int Id { get; set; }
    public virtual int? ParentId { get; set; }
}

static void Main(string[] args)
{
    Entity entity = Mock.Of<Entity>();
    var mock = Mock.Get<Entity>(entity);
    mock.Setup(e => e.ParentId).Returns(11);
    var result = entity.ParentId;
    // now result == 11
}

你可以在你的internals.Object

上使用Mock.Get方法

答案 1 :(得分:0)

创建一个包含2个属性的新实用程序类:

Mock<IDataContext> DbContextMock
Mock<DbSet<InternalTransaction>> InternalTransMock

让您的Utility函数返回此新对象,以便您的测试可以访问这两个对象。