微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

单元测试 – 单元测试LINQ2SQL存储库

我正在采用MsTest和Moq的第一步,并希望对 Linq2sql存储库类进行单元测试.问题是我不希望单元测试来修改我的开发数据库.

哪一种是这种情况的最佳方法

>让每个测试在我的真实开发数据库上运行,但确保每个测试自己清理
>为单元测试创​​建我的开发数据库和dbml的副本,并使用该上下文,以便我可以在每个测试运行之前清除整个数据库
>找出一些嘲弄Datacontext的精心设计的方式(请记住,我是一个总Moq noob).
>完全不一样的东西在每次测试运行之前,可能会自动为我设置数据库

编辑:我刚刚了解到,MBUnit具有一个回滚属性,可以反转由测试用例运行的任何数据库操作.我不是特别关注MSTest,所以这可以简单地解答我的问题吗?

解决方法

我使用一些包装类使用一些基于 http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx的假实现进行嘲笑/伪造数据库.请注意,我最终在我的假数据上下文包装器中实现了SubmitChanges逻辑,以测试我实体的部分类实现中的验证逻辑.我认为这真的是唯一棘手的部分,与Tokeley的实施有很大不同.

我将在下面包含我的FakeDataContextwrapper实现:

public class FakeDataContextwrapper : IDataContextwrapper
{

    public DataContext Context
    {
        get { return null; }
    }

    private List<object> Added = new List<object>();
    private List<object> Deleted = new List<object>();

    private readonly IFakeDatabase mockDatabase;

    public FakeDataContextwrapper( IFakeDatabase database )
    {
        mockDatabase = database;
    }

    protected List<T> InternalTable<T>() where T : class
    {
        return (List<T>)mockDatabase.Tables[typeof( T )];
    }

    #region IDataContextwrapper Members

    public virtual IQueryable<T> Table<T>() where T : class
    {
        return mockDatabase.GetTable<T>();
    }

    public virtual ITable Table( Type type )
    {
        return new FakeTable( mockDatabase.Tables[type],type );
    }

    public virtual void DeleteallOnSubmit<T>( IEnumerable<T> entities ) where T : class
    {
        foreach (var entity in entities)
        {
            DeleteOnSubmit( entity );
        }
    }

    public virtual void DeleteOnSubmit<T>( T entity ) where T : class
    {
        this.Deleted.Add( entity );
    }

    public virtual void InsertAllOnSubmit<T>( IEnumerable<T> entities ) where T : class
    {
        foreach (var entity in entities)
        {
            InsertOnSubmit( entity );
        }
    }

    public virtual void InsertOnSubmit<T>( T entity ) where T : class
    {
        this.Added.Add( entity );
    }

    public virtual void SubmitChanges()
    {
        this.SubmitChanges( ConflictMode.FailOnFirstConflict );
    }

    public virtual void SubmitChanges( ConflictMode failureMode )
    {
        try
        {
            foreach (object obj in this.Added)
            {
                MethodInfo validator = obj.GetType().getmethod( "OnValidate",BindingFlags.Instance | BindingFlags.NonPublic );
                if (validator != null)
                {

                    validator.Invoke( obj,new object[] { ChangeAction.Insert } );
                }
                this.mockDatabase.Tables[obj.GetType()].Add( obj );
            }

            this.Added.Clear();

            foreach (object obj in this.Deleted)
            {
                MethodInfo validator = obj.GetType().getmethod( "OnValidate",BindingFlags.Instance | BindingFlags.NonPublic );
                if (validator != null)
                {
                    validator.Invoke( obj,new object[] { ChangeAction.Delete } );
                }
                this.mockDatabase.Tables[obj.GetType()].Remove( obj );
            }

            this.Deleted.Clear();

            foreach (keyvaluePair<Type,IList> tablePair in this.mockDatabase.Tables)
            {
                MethodInfo validator = tablePair.Key.getmethod( "OnValidate",BindingFlags.Instance | BindingFlags.NonPublic );
                if (validator != null)
                {
                    foreach (object obj in tablePair.Value)
                    {
                        validator.Invoke( obj,new object[] { ChangeAction.Update } );
                    }
                }
            }
        }
        catch (TargetInvocationException e)
        {
            throw e.InnerException;
        }
    }

    public void dispose() { }

    #endregion
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_no=&#39;LJCG001H&#39; THEN dbo.ELTPNAME(a.fw_nu) ELSE d.fm_name END),e.fw_state_nm,f.fw_rmk_nm
if not exists(select name from syscolumns where name=&#39;tod_no&#39; and id=object_id(&#39;iebo09d12&#39;)) alter table iebo09d12 add tod_no varchar(
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_nm,g.fa_name from LJSS007H a (nolock) Left join LJPA002H b (nolock) On a.pa_no =b.pa_no Left jo
要在 SQL Server 2019 中设置定时自动重启,可以使用 Windows 任务计划程序。下面是详细的步骤: 步骤一:创建批处理文件 打开记事本。 输入以下内容: net stop &quot;SQL Server (MSSQLSERVER)&quot; net start &quot;SQ
您收到的错误消息表明数据库 &#39;EastRiver&#39; 的事务日志已满,导致数据库操作失败。要解决这个问题,可以按照以下步骤操作: 1. 备份事务日志首先,备份事务日志以释放空间: BACKUP LOG [EastRiver] TO DISK = N&#39;C:\Backup\East
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标识ID,若不知道怎么查询数据库的标识ID, 打开SQL Server management studio,点击工具。选择SQL Server Profiler。 登录,登录成功后,如果有个默认弹窗,先取消 新建追踪 命名
--最新的解决方法 --先创建用户帐户,不进行授权,然后通过下面的SQL语句将该用户帐户关联至对应的数据库用户。优点是避免了重新授权的操作。 USE tempdbEXEC sp_change_users_login &#39;Update_One&#39;, &#39;iemis&#39;, &#3
命令: ALTER TABLE 表名 add 列名 数据类型 default 默认值 not null 例如: ALTER TABLE LJEL005H add el_req int default 15 not null
declare @i int set @i=340 while @i&lt;415 begin set @i=@iʱ insert into LJWK007H select &#39;2024&#39;,&#39;28&#39;,&#39;9110&#39;,&#39;3PTSD621000000