使用 HashSet 的假数据库上下文进行 C# 单元测试(pluralsight 代码)(新 Q)

发布于 2024-11-07 07:19:50 字数 4176 浏览 0 评论 0原文

简短版本:

在此视频中,Scott Allen 先生说明如何测试控制器。 但他没有显示该类的完整代码:FakeDbContext。 有人可以帮我完成吗?他在视频中的 06:15 分钟展示了“测试控制器”的课程。

长版

在学校我有一门选修课,我们学习 C#。我的考试项目是一个使用MVC3的ASP网站。 为了快速学习,我观看了 PluralSight 的视频。我的问题是关于 此视频 他解释了如何测试控制器。所以我尝试了: 我制作了一个具有简单索引方法的控制器:

public class Round1Controller : Controller
{
    IDbContext _db;

    public Round1Controller()
    {
        _db = new Entities();
    }
    
    public Round1Controller(IDbContext db)
    {
        _db = db;
    }
    
    public ActionResult Index()
    {
        var model = _db.ELECTIVES.ToList();

        return View(model);
    }

如您所见,我已经尝试创建上下文。 索引方法是我想测试的方法。 他要做的下一件事是在测试项目中创建一个名为 FakeDbContext 的类。

但遗憾的是他只显示了部分代码,我花了很多时间试图弄清楚他如何为 HashSet 创建 get 方法。

以下是您可以从视频中看到的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EESS.Models;

namespace EESS.Tests
{
class FakeDbContext : IDbContext
{
    public IQueryable<Restaurant> Restaurants
    {
        get { return _map.Get<Restaurant>().asQueryable(); }
        set { _map.Use<Restaurant>(value); }
    }
    public IQueryable<Review> Reviews
    {
        get { return _map.Get<Review>().asQueryable(); }
        set { _map.Use<Review>(value); }
    }

    public int SaveChanges()
    {
        ChangesSaved = true;
        return 0;
    }

    public bool ChangesSaved { get; set; }

    public T Attach<T>(T entity) where T : class
    {
        _map.Get<T>().Add(entity);
        return entity;
    }
    public T Add<T>(T entity) where T : class
    {
        _map.Get<T>().Add(entity);
        return entity;
    }

    public T Delete<T>(T entity) where T : class
    {
        _map.Get<T>().Remove(entity);
        return entity;
    }

    SetMap _map = new SetMap();

    class SetMap : KeyedCollection<Type, object>
    {
        public HashSet<T> Use<T>(IEnumerable<T> sourceData)
        {
            var set = new HashSet<T>(sourceData);
            if (Contains(typeof(T)))
            {
                Remove(typeof(T));
            }
            Add(set);
            return set;
        }
    }
}
}

为了结束长版本,我的问题是我在 _Map.Get 上遇到错误。 不包含定义或扩展方法

编辑!第 2 部分:

在 @xelibrion 出色的回答之后,它终于起作用了。

但接下来又出现了另一个问题。

IDbContext 类如下所示:

public interface IDbContext
    {
        IQueryable<ELECTIVES> ELECTIVES { get; }
        int SaveChanges();
        T Attach<T>(T entity) where T : class;
        T Add<T>(T entity) where T : class;
        T Delete<T>(T entity) where T : class;
    }
    

当我将此接口添加到我的实体类时,它不希望我实现这些方法。 PluralSight 像这样实现它们:

public DbSet<ELECTIVES> electives { get; set; }

    IQueryable<ELECTIVES> IDbContext.ELECTIVES
    {
        get { return electives; }
    }

    int IDbContext.SaveChanges()
    {
        return SaveChanges();
    }
    
    T IDbContext.Add<T>(T entity)
    {
        return Set<T>().Add(entity);
    }
    
    T IDbContext.Delete<T>(T entity)
    {
        return Set<T>().Remove(entity);
    }
    
    T IDbContext.Attach<T>(T entity)
    {
        
        var entry = Entry(entity);
        entry.State = System.Data.EntityState.Modified;
        return entity;
        return Set<T>().Add(entity);
    }

但是我的实体模型中的“_dbModel.Designer.cs”类不知道 Set 和 Entry 是什么,只建议我创建一个方法存根。这个类中有更多的代码,所以如果需要,只需询问其余的:)我已将餐厅更改为选修课,因为这是我的数据库中的表名称。

这是我忘记的“使用”吗?我又看了一遍视频,他的 DB 类中没有方法存根。

The short version:

In this video, Mr. Scott Allen explains how to test a controller.
But he does not show the full code of the class: FakeDbContext.
Is there someone who can help me finish it? He shows the class at, 06:15 min in the video for "testing controllers".

The long version

At school I have a elective where we learn C#. My exam project is a ASP site using MVC3.
To learn it fast, i have seen videos from PluralSight. My question is about some code that are in this video
He explains how to test controllers. So i tried:
I have made a controller which has a simple index method:

public class Round1Controller : Controller
{
    IDbContext _db;

    public Round1Controller()
    {
        _db = new Entities();
    }
    
    public Round1Controller(IDbContext db)
    {
        _db = db;
    }
    
    public ActionResult Index()
    {
        var model = _db.ELECTIVES.ToList();

        return View(model);
    }

As you can see i have already tried to make a context.
The index method is the one i want to TEST.
The next thing he does is to make a class called, FakeDbContext, in the test project.

But sadly he only show a part of the code, and i have used a lot of hours trying to figure out how he creates a get method to a HashSet.

Here is the code that you can see from the video:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EESS.Models;

namespace EESS.Tests
{
class FakeDbContext : IDbContext
{
    public IQueryable<Restaurant> Restaurants
    {
        get { return _map.Get<Restaurant>().asQueryable(); }
        set { _map.Use<Restaurant>(value); }
    }
    public IQueryable<Review> Reviews
    {
        get { return _map.Get<Review>().asQueryable(); }
        set { _map.Use<Review>(value); }
    }

    public int SaveChanges()
    {
        ChangesSaved = true;
        return 0;
    }

    public bool ChangesSaved { get; set; }

    public T Attach<T>(T entity) where T : class
    {
        _map.Get<T>().Add(entity);
        return entity;
    }
    public T Add<T>(T entity) where T : class
    {
        _map.Get<T>().Add(entity);
        return entity;
    }

    public T Delete<T>(T entity) where T : class
    {
        _map.Get<T>().Remove(entity);
        return entity;
    }

    SetMap _map = new SetMap();

    class SetMap : KeyedCollection<Type, object>
    {
        public HashSet<T> Use<T>(IEnumerable<T> sourceData)
        {
            var set = new HashSet<T>(sourceData);
            if (Contains(typeof(T)))
            {
                Remove(typeof(T));
            }
            Add(set);
            return set;
        }
    }
}
}

To end the long version, my problem is i get a error on _Map.Get.
Does not contain a definition or extension method.

EDIT! PART 2:

After @xelibrion great answer it finally worked.

But then another problem come up.

The IDbContext class looks like this:

public interface IDbContext
    {
        IQueryable<ELECTIVES> ELECTIVES { get; }
        int SaveChanges();
        T Attach<T>(T entity) where T : class;
        T Add<T>(T entity) where T : class;
        T Delete<T>(T entity) where T : class;
    }
    

When i add this interface to my Entities Class it offcouse expect me to implement the methods.
PluralSight implements them like this:

public DbSet<ELECTIVES> electives { get; set; }

    IQueryable<ELECTIVES> IDbContext.ELECTIVES
    {
        get { return electives; }
    }

    int IDbContext.SaveChanges()
    {
        return SaveChanges();
    }
    
    T IDbContext.Add<T>(T entity)
    {
        return Set<T>().Add(entity);
    }
    
    T IDbContext.Delete<T>(T entity)
    {
        return Set<T>().Remove(entity);
    }
    
    T IDbContext.Attach<T>(T entity)
    {
        
        var entry = Entry(entity);
        entry.State = System.Data.EntityState.Modified;
        return entity;
        return Set<T>().Add(entity);
    }

But my "_dbModel.Designer.cs" class from my entity model does not know what Set and Entry is, and only suggest i make a method stub. There are a lot more code in this class, so if its need just ask for the rest :) I have changed Restaurants to Electives since thats the table name i my DB.

Is it a "using" i have forgotten? I have seen the video again, and he does not have a method stub in his DB class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

讽刺将军 2024-11-14 07:19:50

我想 SetMap 类的完整版本应该如下所示

class SetMap : KeyedCollection<Type, object>
{
    public HashSet<T> Use<T>(IEnumerable<T> sourceData)
    {
        var set = new HashSet<T>(sourceData);
        if (Contains(typeof(T)))
        {
            Remove(typeof(T));
        }
        Add(set);
        return set;
    }

    public HashSet<T> Get <T>()
    {
        return (HashSet<T>) this[typeof(T)];
    }

    protected override Type GetKeyForItem(object item)
    {
        return item.GetType().GetGenericArguments().Single();
    }
}

I suppose full version of SetMap class should look like this

class SetMap : KeyedCollection<Type, object>
{
    public HashSet<T> Use<T>(IEnumerable<T> sourceData)
    {
        var set = new HashSet<T>(sourceData);
        if (Contains(typeof(T)))
        {
            Remove(typeof(T));
        }
        Add(set);
        return set;
    }

    public HashSet<T> Get <T>()
    {
        return (HashSet<T>) this[typeof(T)];
    }

    protected override Type GetKeyForItem(object item)
    {
        return item.GetType().GetGenericArguments().Single();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文