在lambda表达式中使用泛型或如何使用泛型访问dbset

时间:2017-10-19 08:21:26

标签: c# generics lambda

我正在使用NUnit,Moq,C#和.NET Framework 4.7开发一个测试项目。

我有两种方法几乎相同:

using Microsoft.EntityFrameworkCore;
using Moq;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;

private void MockProducts(Mock<TRZFDbContext> mockContext, List<Product> data)
{
    IQueryable<Product> queryable = data.AsQueryable();

    var mockSet = new Mock<DbSet<Product>>();

    mockSet.As<IQueryable<Product>>().Setup(m => m.Provider).Returns(queryable.Provider);
    mockSet.As<IQueryable<Product>>().Setup(m => m.Expression).Returns(queryable.Expression);
    mockSet.As<IQueryable<Product>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
    mockSet.As<IQueryable<Product>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());
    mockSet.Setup(d => d.Add(It.IsAny<Product>())).Callback<Product>((s) => data.Add(s));
    mockSet.Setup(d => d.Remove(It.IsAny<Product>())).Callback<Product>((s) => data.Remove(s));

    mockContext.Setup(m => m.Product).Returns(mockSet.Object);
}

private void MockEmvoProducts(Mock<TRZFDbContext> mockContext, List<EmvoProduct> data)
{
    IQueryable<EmvoProduct> queryable = data.AsQueryable();

    var mockSet = new Mock<DbSet<EmvoProduct>>();

    mockSet.As<IQueryable<EmvoProduct>>().Setup(m => m.Provider).Returns(queryable.Provider);
    mockSet.As<IQueryable<EmvoProduct>>().Setup(m => m.Expression).Returns(queryable.Expression);
    mockSet.As<IQueryable<EmvoProduct>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
    mockSet.As<IQueryable<EmvoProduct>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());
    mockSet.Setup(d => d.Add(It.IsAny<EmvoProduct>())).Callback<EmvoProduct>((s) => data.Add(s));
    mockSet.Setup(d => d.Remove(It.IsAny<EmvoProduct>())).Callback<EmvoProduct>((s) => data.Remove(s));

    mockContext.Setup(m => m.EmvoProduct).Returns(mockSet.Object);
}

我可以使用泛型创建一个泛型方法来更改第二个参数data。但我的问题是在最后一句话:

mockContext.Setup(m => m.Product).Returns(mockSet.Object);

mockContext.Setup(m => m.EmvoProduct).Returns(mockSet.Object);

m.ProductProduct的DbSet,m.EmvoProductEmvoProduct的DbSet。

有没有办法让lambda表达式使用泛型?或许还有其他方法。

1 个答案:

答案 0 :(得分:1)

您应该可以使用在公共静态类

中声明类似的扩展函数来执行此操作
public static class DBSetExtensions {

    public static void Setup<T>(this DbSet<T> list, Action<T> lamda){
        lamda(objectFromDbSet);
    }

}

现在在任何一个类中都有一个带泛型的DbSet,你应该可以使用

mockSet.Setup(d => d.Add(It.IsAny<EmvoProduct>()))

对于链式函数Callback,您需要将上述函数的返回类型从void更改为它们在setup中返回的任何对象。