【问题标题】:How to attach a moq entity to a mock datacontext如何将最小起订量实体附加到模拟数据上下文
【发布时间】:2014-08-08 17:10:47
【问题描述】:

我对模拟的想法很陌生,我正在使用 Moq 对这段代码进行单元测试。

using Forum = ProForum.Domain.Database.tblForum;
using Thread = ProForum.Domain.Database.tblThread;

namespace ProForum.Domain.Concrete
{
   public class ForumRepository : IForumRepository
   {
      protected Table<Forum> DataTable;
      private ProForumDataContext dataContext;

      public ForumRepository(ProForumDataContext dataContext)
      {
         DataTable = dataContext.GetTable<Forum>();
      }

      public Forum GetForumById(int id)
      {
         try
         {
            return DataTable.Single(f => f.tblForumID.Equals(id));
         }
         catch (Exception e)
         {
            return null;
         }
      }
   }
}

我想测试GetForumById的方法。为此,我想创建 ProForumDataContext 的模拟并将模拟论坛插入其中。我应该如何为 ProForumDataContext 设置模拟,以便当我在其上调用 GetTable 方法时,它返回一个包含模拟论坛的表。表是System.Data.Linq.Table 类。

我正在做这样的事情:

[TestMethod]
public void Can_Get_Forum_ById()
{
   //arrange
   Mock<Forum> mockForum = new Mock<Forum>();
   mockForum.Object.tblForumID = 1;
   //Mock<Table<Forum>> tableMock = new Mock<Table<Forum>>();
   //tableMock.Object.Attach(mockForum);
   Mock<DiscussionForumDataContext> mockContext = new Mock<DiscussionForumDataContext>();
   mockContext.Setup).
   Returns();
}

我没有得到传递给设置的内容和返回的内容。 论坛类:

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.tblForums")]
    public partial class tblForum : INotifyPropertyChanging, INotifyPropertyChanged
    {

        private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

        private int _tblForumID;
        private string _Name;
        private string _Description;
        private int _tblUserLogin_ID;
        private int _TotalPosts;
        private int _TotalThreads;
        private bool _Active;
private System.Data.Linq.Binary _RowVersion;

        private System.DateTime _Modified;

        private System.DateTime _Created;

        private EntitySet<tblThread> _tblThreads;
        public tblForum()
        {
            this._tblThreads = new EntitySet<tblThread>(new Action<tblThread>(this.attach_tblThreads), new Action<tblThread>(this.detach_tblThreads));
            OnCreated();
        }

        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_tblForumID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true, UpdateCheck=UpdateCheck.Never)]
        public int tblForumID
        {
            get
            {
                return this._tblForumID;
            }
            set
            {
                if ((this._tblForumID != value))
                {
                    this.OntblForumIDChanging(value);
                    this.SendPropertyChanging();
                    this._tblForumID = value;
                    this.SendPropertyChanged("tblForumID");
                    this.OntblForumIDChanged();
                }
            }
    }

【问题讨论】:

    标签: c# linq unit-testing moq


    【解决方案1】:

    我个人不建议模拟数据上下文。 LINQ to SQL 或实体框架的设计很复杂。 DataContext 的问题在于它在构造函数中建立连接,因此您最终不会与数据库的依赖关系隔离。

    我会推荐一个包装它的类,它还定义了一个接口,并在你需要的任何地方使用该接口引用,它可以有如下方法:

    public interface IUnitOfWork
    {
       Table<T> GetTable();
       void SubmitChanges();
    }
    

    并实施您使用的任何其他方法。会简单很多。

    【讨论】:

      【解决方案2】:

      您可以使用 Moq 来模拟接口,而不是类。您需要一个 ProForumDataContext 接口(例如 IProForumDataContext),该接口带有一个返回 GetTable() 的方法。然后您需要更改 ForumRepository 以接受 IProForumDataContext。

      然后你会像这样模拟:

      Mock<IProForumDataContext> mockContext = new Mock<IProForumDataContext>();
      mockContext.Setup(context => context.GetTable<Forum>()).Returns(forum);
      

      但让我们退后一步。您的代码可能更具可测试性。 ForumRepository 构造函数接受 ProForumDataContext 是否有原因?它可以直接接受表格。这称为“传递所需的方法”。

      不确定你的论坛类来自哪里,但你也需要一个接口来模拟它。

      【讨论】:

      • 您可以模拟类(抽象的或具体的),但只能设置用虚拟定义的方法。
      • @user3339997 :在问题中添加了论坛类代码。不确定为什么 ProForumDataContext 在 repos 构造函数中传递。这段代码不是我写的。只是测试它。
      • @user3339997 : 看来,DataContext 在 ForumRepository 构造函数中被传递是符合 Repository 模式的。
      猜你喜欢
      • 2010-09-06
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 1970-01-01
      • 2014-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多