相关疑难解决方法(0)

如何模拟EntityFramework的IQueryable实现的局限性

我目前正在为MVC4应用程序中的存储库实现编写单元测试.为了模拟数据上下文,我开始采用这篇文章中的一些想法,但我现在发现了一些限制,让我怀疑是否有可能正确模拟IQueryable.

特别是,我已经看到了一些测试通过但代码在生产中失败的情况,并且我无法找到任何方法来模拟导致此失败的行为.

例如,以下代码段用于选择Post属于预定义类别列表的实体:

var posts = repository.GetEntities<Post>(); // Returns IQueryable<Post>
var categories = GetCategoriesInGroup("Post"); // Returns a fixed list of type Category
var filtered = posts.Where(p => categories.Any(c => c.Name == p.Category)).ToList();
Run Code Online (Sandbox Code Playgroud)

在我的测试环境中,我试图嘲弄posts使用假DbSet上面提到的实施,同时也通过创建ListPost实例并将其转换为IQueryable使用AsQueryable()扩展方法.这两种方法都在测试条件下工作,但代码实际上在生产中失败,但有以下例外:

System.NotSupportedException : Unable to create a constant value of type 'Category'. Only primitive types or enumeration types are supported in this context.

虽然像这样的LINQ问题很容易解决,但真正的挑战是找到它们,因为它们不会在测试环境中显示出来.

我期望我可以嘲笑实体框架的实施行为,这是不现实的IQueryable吗?

谢谢你的想法,

蒂姆.

entity-framework iqueryable mocking

28
推荐指数
1
解决办法
5834
查看次数

如何在单元测试中伪造 DbEntityEntry&lt;T&gt; Entry(T实体) 方法?

在我的控制器的单元测试中,我模拟了数据库上下文类,将一个假数据库上下文对象注入到控制器构造函数中。假上下文类具有假 DBSet 类,并且它们工作正常。但是,我不知道如何伪造 POST 单元测试的 DbEntityEntry.Entry() 方法。简化的POST方法代码如下

    [ResponseType(typeof(Trip))]
    public async Task<IHttpActionResult> PostTrip(Trip trip)
    {
        db.Trips.Add(trip);
        await db.SaveChangesAsync();

        //Load driver user object
        db.Entry(trip).Reference(x => x.User).Load();

        var tripDTO = new TripDTO()
        {
            Id = trip.Id,
            Status = trip.Status,
            BookedSeats = trip.BookedSeats,
            DriverName = trip.User.Name,
        };

        return CreatedAtRoute("DefaultApi", new { id = trip.Id }, tripDTO);
    }
Run Code Online (Sandbox Code Playgroud)

显然,我必须以某种方式模拟 DbEntityEntry.Entry() 方法,以使 db.Entry(trip).Reference() 方法能够与 LINQ 表达式一起使用。如果您以前遇到过类似的问题,可以帮忙吗?

多谢。

c# unit-testing entity-framework mocking dbcontext

5
推荐指数
0
解决办法
3539
查看次数