gpt4 book ai didi

c# - 测试通用接口(interface)时出现奇怪的接口(interface)/TContext 错误

转载 作者:太空宇宙 更新时间:2023-11-03 15:01:55 25 4
gpt4 key购买 nike

尝试对通用存储库 C# 进行单元测试时,我收到一个奇怪的错误“无法从 IStudentContext 转换为 TestStudentContext”。看来我需要在我的界面中重新实现 .Set() ,对吗?为简洁起见省略了一些代码,但这是基本设置。请原谅大块代码,我会在底部添加一些额外的上下文!

IStudentContext.cs

public interface IStudentContext : IDisposable
{
Database Database { get; }

// Irrelevant tables omitted
DbSet<Class> Classes { get; set; }

int SaveChanges();

Task<int> SaveChangesAsync();
}

StudentContext.cs

public class StudentContext : DbContext, IStudentContext
{
public StudentContext() : base("name=StudentContext") {}

// Irrelevant tables omitted
public virtual DbSet<Class> Classes { get; set; }
}

TestStudentContext.cs

public class TestStudentContext : DbContext, IStudentContext
{
public TestStudentContext(DbConnection connection) : base(connection, contextOwnsConnection: true) {}

// Irrelevant tables omitted
public virtual DbSet<Class> Classes { get; set; }
}

EntityFrameworkReadOnlyRepository.cs

public class EntityFrameworkReadOnlyRepository<TContext> : IGenericReadOnlyRepository where TContext : DbContext, IStudentContext
{
protected readonly TContext Context;

public EntityFrameworkReadOnlyRepository(TContext context)
{
Context = context;
}

// Irrelevant generic repo methods omitted
public IEnumerable<TEntity> Get<TEntity>(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string include = null, int? skip = null, int? take = null)
{
return GetQueryable(filter, orderBy, include, skip, take).ToList();
}

protected virtual IQueryable<TEntity> GetQueryable<TEntity>(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string include = null, int? skip = null, int? take = null)
{
include = include ?? string.Empty;
IQueryable<TEntity> query = Context.Set<TEntity>();

if (filter != null)
query = query.Where(filter);

query = include.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Aggregate(query, (current, property) => current.Include(property));

if (orderBy != null)
query = orderBy(query);

if (skip.HasValue)
query = query.Skip(skip.Value);

if (take.HasValue)
query = query.Take(take.Value);

return query;
}
}

StudentRepositoryTests.cs

public class StudentRepositoryTests
{
private IStudentContext Context { get; set; }

[TestInitialize]
public void Initialize()
{
Context = new TestStudentContext(Effort.DbConnectionFactory.CreateTransient());
}

[TestMethod]
public void GetClasses_OrdersCorrectly()
{
// Calls to Context.Classes.Add() to set up DB omitted

Context.SaveChanges();

var repository = new EntityFrameworkReadOnlyRepository<TestStudentContext>(Context);

var results = repository.Get<Classes>().ToArray();

// Assertions omitted
}
}

正如所写,我在 Context 上收到错误消息在var repository我的测试课的行。错误状态 Argument 1: cannot convert from 'IStudentContext' to 'TestStudentContext' .如果我将该行更改为 var repository = new EntityFrameworkReadOnlyRepository<IStudentContext>(Context); , 然后我得到一个错误 The type 'IStudentContext' cannot be used as type parameter 'TContext' in the generic type or method 'EntityFrameworkReadOnlyRepository<TContext>'. There is no implicit reference conversion from 'IStudentContext' to 'System.Data.Entity.DbContext'.

看起来如果我为 IStudentContext 中的所有数据库表实现 DbSet这可能解决了这个问题,但感觉就像我重新实现了很多代码只是为了能够测试一些东西,所以我认为会有更简单的方法来做到这一点。

最佳答案

var repository = new EntityFrameworkReadOnlyRepository<TestStudentContext>(Context);

Context类型为 IStudentContext .因此,您不能将该值传递给期望 TestStudentContext 的 ctor .

一个简单的解决方法是制作private IStudentContext Context { get; set; }类型 TestStudentContext .或者,如果你想保留它 IStudentContext然后转换,或者找到另一种方法来传递该值而不向上转换为 IStudentContext在此过程中首先丢失类型信息。

It seems I need to reimplement .Set() in my interface, is that right?

那应该没有必要。编译器消息指向我解决的问题。


在您的存储库中,您已选择让调用者指定位置、排序依据等。在我看来,这不是一种有用的方法。似乎只有一个 QueryTable<T>() 更好方法并使调用者构造查询。您可以制作一个辅助函数来构建这样的查询(我认为这没有用),但没有必要让存储库负责构建 LINQ 查询。

我还粗略地注意到 TContext参数似乎没有必要。你可以使用 DbContext直接简化。

关于c# - 测试通用接口(interface)时出现奇怪的接口(interface)/TContext 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45841566/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com