gpt4 book ai didi

c# - 模拟 EF 核心 dbcontext 和 dbset

转载 作者:太空狗 更新时间:2023-10-29 18:13:03 26 4
gpt4 key购买 nike

我正在使用 ASP.NET Core 2.2、EF Core 和 MOQ。运行测试时出现此错误:

Message: System.NotSupportedException : Invalid setup on a non-virtual (overridable in VB) member: x => x.Movies

我做错了什么?

public class MovieRepositoryTest
{
private readonly MovieRepository _sut;

public MovieRepositoryTest()
{
var moviesMock = CreateDbSetMock(GetFakeListOfMovies());
var mockDbContext = new Mock<MovieDbContext>();
mockDbContext.Setup(x => x.Movies).Returns(moviesMock.Object);
_sut = new MovieRepository(mockDbContext.Object);
}

[Fact]
public void GetAll_WhenCalled_ReturnsAllItems()
{
//Act
var items = _sut.GetAll();

//Assert
Assert.Equal(3, items.Count());
}

private IEnumerable<Movie> GetFakeListOfMovies()
{
var movies = new List<Movie>
{
new Movie {Id = 1, Title = "Movie 1", YearOfRelease = 2018, Genre = "Action"},
new Movie {Id = 2, Title = "Movie 2", YearOfRelease = 2018, Genre = "Action"},
new Movie {Id = 3, Title = "Movie 3", YearOfRelease = 2019, Genre = "Action"}
};

return movies;
}

private static Mock<DbSet<T>> CreateDbSetMock<T>(IEnumerable<T> elements) where T : class
{
var elementsAsQueryable = elements.AsQueryable();
var dbSetMock = new Mock<DbSet<T>>();

dbSetMock.As<IQueryable<T>>().Setup(m => m.Provider).Returns(elementsAsQueryable.Provider);
dbSetMock.As<IQueryable<T>>().Setup(m => m.Expression).Returns(elementsAsQueryable.Expression);
dbSetMock.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(elementsAsQueryable.ElementType);
dbSetMock.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(elementsAsQueryable.GetEnumerator());

return dbSetMock;
}
}

这是我的数据库上下文,带有 Movie dbSet:

public class MovieDbContext: DbContext
{
public MovieDbContext(DbContextOptions<MovieDbContext> options) : base(options)
{

}

public DbSet<Movie> Movies { get; set; }
}

以及要测试的方法为 GetAll 的 Repository:

 public class MovieRepository: IMovieRepository
{
private readonly MovieDbContext _moviesDbContext;
public MovieRepository(MovieDbContext moviesDbContext)
{
_moviesDbContext = moviesDbContext;
}

public IEnumerable<Movie> GetAll()
{
return _moviesDbContext.Movies;
}
}

最佳答案

我看到您在 MovieRepository 中使用 EF core DbContext。因此,使用 EF Core InMemory 数据库而不是使用 mock 将是一个不错的选择。这也将降低复杂性。

按如下方式编写您的 GetAllTest() 方法:

[Fact]
public void GetAllTest()
{
var options = new DbContextOptionsBuilder<MovieDbContext>()
.UseInMemoryDatabase(databaseName: "MovieListDatabase")
.Options;

// Insert seed data into the database using one instance of the context
using (var context = new MovieDbContext(options))
{
context.Movies.Add(new Movie {Id = 1, Title = "Movie 1", YearOfRelease = 2018, Genre = "Action"});
context.Movies.Add(new Movie {Id = 2, Title = "Movie 2", YearOfRelease = 2018, Genre = "Action"});
context.Movies.Add(new Movie {Id = 3, Title = "Movie 3", YearOfRelease = 2019, Genre = "Action"});
context.SaveChanges();
}

// Use a clean instance of the context to run the test
using (var context = new MovieDbContext(options))
{
MovieRepository movieRepository = new MovieRepository(context);
List<Movies> movies == movieRepository.GetAll();

Assert.Equal(3, movies.Count);
}
}

注意:不要忘记安装 Microsoft.EntityFrameworkCore.InMemory nuget 包,如下所示:

Install-Package Microsoft.EntityFrameworkCore.InMemory

更多详情:Testing with InMemory

关于c# - 模拟 EF 核心 dbcontext 和 dbset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54219742/

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