C# 重构不同类型的重复代码

C# 重构不同类型的重复代码,c#,oop,generics,inheritance,refactoring,C#,Oop,Generics,Inheritance,Refactoring,我构建了一些测试助手方法,这些方法为实体框架构建了一个模拟DBContext。这些方法包含重复的代码,我认为必须有更好的方法来做到这一点。我就是不知道怎么做。我尝试创建一个MockDbContextBuilder类,但失败了,因为我无法拥有DbSet。有什么想法吗?以下是我试图重构为一种方法的三个示例: private Mock<IPSNContext> BuildMockDbContext(List<TestEntity> list) {

我构建了一些测试助手方法,这些方法为实体框架构建了一个模拟DBContext。这些方法包含重复的代码,我认为必须有更好的方法来做到这一点。我就是不知道怎么做。我尝试创建一个MockDbContextBuilder类,但失败了,因为我无法拥有DbSet。有什么想法吗?以下是我试图重构为一种方法的三个示例:

    private Mock<IPSNContext> BuildMockDbContext(List<TestEntity> list)
    {
        _mockDbSet = new Mock<DbSet<TestEntity>>();
        _mockDbSet.As<IQueryable<TestEntity>>().Setup(m => m.Provider).Returns(list.AsQueryable().Provider);
        _mockDbSet.As<IQueryable<TestEntity>>().Setup(m => m.Expression).Returns(list.AsQueryable().Expression);
        _mockDbSet.As<IQueryable<TestEntity>>().Setup(m => m.ElementType).Returns(list.AsQueryable().ElementType);
        _mockDbSet.As<IQueryable<TestEntity>>().Setup(m => m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());

        foreach (var item in list)
        {
            _mockDbSet.Setup(m => m.Find(item.Id)).Returns(item);
        }

        var mockContext = new Mock<IPSNContext>();
        mockContext.Setup(c => c.Set<TestEntity>())
                    .Returns(_mockDbSet.Object);
        return mockContext;
    }

    private Mock<IPSNContext> BuildMockDbContext(List<MessageBoardTopic> list)
    {
        _mockDbSet = new Mock<DbSet<MessageBoardTopic>>();
        _mockDbSet.As<IQueryable<MessageBoardTopic>>().Setup(m => m.Provider).Returns(list.AsQueryable().Provider);
        _mockDbSet.As<IQueryable<MessageBoardTopic>>().Setup(m => m.Expression).Returns(list.AsQueryable().Expression);
        _mockDbSet.As<IQueryable<MessageBoardTopic>>().Setup(m => m.ElementType).Returns(list.AsQueryable().ElementType);
        _mockDbSet.As<IQueryable<MessageBoardTopic>>().Setup(m => m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());

        foreach (var item in list)
        {
            _mockDbSet.Setup(m => m.Find(item.Id)).Returns(item);
        }

        var mockContext = new Mock<IPSNContext>();
        mockContext.Setup(c => c.Set<MessageBoardTopic>())
                    .Returns(_mockDbSet.Object);        
        return mockContext;
    }

    private Mock<IPSNContext> BuildMockDbContext(List<MessageBoardReply> list)
    {
        _mockDbSet = new Mock<DbSet<MessageBoardReply>>();
        _mockDbSet.As<IQueryable<MessageBoardReply>>().Setup(m => m.Provider).Returns(list.AsQueryable().Provider);
        _mockDbSet.As<IQueryable<MessageBoardReply>>().Setup(m => m.Expression).Returns(list.AsQueryable().Expression);
        _mockDbSet.As<IQueryable<MessageBoardReply>>().Setup(m => m.ElementType).Returns(list.AsQueryable().ElementType);
        _mockDbSet.As<IQueryable<MessageBoardReply>>().Setup(m => m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());

        foreach (var item in list)
        {
            _mockDbSet.Setup(m => m.Find(item.Id)).Returns(item);
        }

        var mockContext = new Mock<IPSNContext>();
        mockContext.Setup(c => c.Set<MessageBoardReply>())
                    .Returns(_mockDbSet.Object);
        return mockContext;
    }
private Mock BuildMockDbContext(列表)
{
_mockDbSet=newmock();
_mockDbSet.As().Setup(m=>m.Provider).返回(list.AsQueryable().Provider);
_mockDbSet.As().Setup(m=>m.Expression).Returns(list.AsQueryable().Expression);
_mockDbSet.As().Setup(m=>m.ElementType).Returns(list.AsQueryable().ElementType);
_mockDbSet.As().Setup(m=>m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());
foreach(列表中的变量项)
{
_mockDbSet.Setup(m=>m.Find(item.Id)).Returns(item);
}
var mockContext=new Mock();
mockContext.Setup(c=>c.Set())
.Returns(_mockDbSet.Object);
返回上下文;
}
私有模拟BuildMockDbContext(列表)
{
_mockDbSet=newmock();
_mockDbSet.As().Setup(m=>m.Provider).返回(list.AsQueryable().Provider);
_mockDbSet.As().Setup(m=>m.Expression).Returns(list.AsQueryable().Expression);
_mockDbSet.As().Setup(m=>m.ElementType).Returns(list.AsQueryable().ElementType);
_mockDbSet.As().Setup(m=>m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());
foreach(列表中的变量项)
{
_mockDbSet.Setup(m=>m.Find(item.Id)).Returns(item);
}
var mockContext=new Mock();
mockContext.Setup(c=>c.Set())
.Returns(_mockDbSet.Object);
返回上下文;
}
私有模拟BuildMockDbContext(列表)
{
_mockDbSet=newmock();
_mockDbSet.As().Setup(m=>m.Provider).返回(list.AsQueryable().Provider);
_mockDbSet.As().Setup(m=>m.Expression).Returns(list.AsQueryable().Expression);
_mockDbSet.As().Setup(m=>m.ElementType).Returns(list.AsQueryable().ElementType);
_mockDbSet.As().Setup(m=>m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());
foreach(列表中的变量项)
{
_mockDbSet.Setup(m=>m.Find(item.Id)).Returns(item);
}
var mockContext=new Mock();
mockContext.Setup(c=>c.Set())
.Returns(_mockDbSet.Object);
返回上下文;
}

您可以使用泛型类型的方法,如下所示:

    private Mock<IPSNContext> BuildMockDbContext<T>(List<T> list)
    {
                _mockDbSet = new Mock<DbSet<T>>();
                _mockDbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(list.AsQueryable().Provider);
                _mockDbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(list.AsQueryable().Expression);
                _mockDbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(list.AsQueryable().ElementType);
                _mockDbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());

                foreach (var item in list)            
                    _mockDbSet.Setup(m => m.Find(item.Id)).Returns(item);            

                var mockContext = new Mock<IPSNContext>();
                mockContext.Setup(c => c.Set<MessageBoardTopic>())
                            .Returns(_mockDbSet.Object);

                return mockContext;
   }
private Mock BuildMockDbContext(列表)
{
_mockDbSet=newmock();
_mockDbSet.As().Setup(m=>m.Provider).返回(list.AsQueryable().Provider);
_mockDbSet.As().Setup(m=>m.Expression).Returns(list.AsQueryable().Expression);
_mockDbSet.As().Setup(m=>m.ElementType).Returns(list.AsQueryable().ElementType);
_mockDbSet.As().Setup(m=>m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());
foreach(列表中的变量项)
_mockDbSet.Setup(m=>m.Find(item.Id)).Returns(item);
var mockContext=new Mock();
mockContext.Setup(c=>c.Set())
.Returns(_mockDbSet.Object);
返回上下文;
}

您可以使用泛型类型的方法,如下所示:

    private Mock<IPSNContext> BuildMockDbContext<T>(List<T> list)
    {
                _mockDbSet = new Mock<DbSet<T>>();
                _mockDbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(list.AsQueryable().Provider);
                _mockDbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(list.AsQueryable().Expression);
                _mockDbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(list.AsQueryable().ElementType);
                _mockDbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());

                foreach (var item in list)            
                    _mockDbSet.Setup(m => m.Find(item.Id)).Returns(item);            

                var mockContext = new Mock<IPSNContext>();
                mockContext.Setup(c => c.Set<MessageBoardTopic>())
                            .Returns(_mockDbSet.Object);

                return mockContext;
   }
private Mock BuildMockDbContext(列表)
{
_mockDbSet=newmock();
_mockDbSet.As().Setup(m=>m.Provider).返回(list.AsQueryable().Provider);
_mockDbSet.As().Setup(m=>m.Expression).Returns(list.AsQueryable().Expression);
_mockDbSet.As().Setup(m=>m.ElementType).Returns(list.AsQueryable().ElementType);
_mockDbSet.As().Setup(m=>m.GetEnumerator()).Returns(list.AsQueryable().GetEnumerator());
foreach(列表中的变量项)
_mockDbSet.Setup(m=>m.Find(item.Id)).Returns(item);
var mockContext=new Mock();
mockContext.Setup(c=>c.Set())
.Returns(_mockDbSet.Object);
返回上下文;
}

这是有效的。谢谢因为DbSet期望T是一个类,所以我只需要添加私有的Mock-BuildMockDbContext(List-List),tenty:class,new()就是这样工作的。谢谢因为DbSet期望T是一个类,所以我只需要添加私有的Mock-BuildMockDbContext(列表),其中tenty:class,new()