没有数据库的单元测试:Linq to SQL

LCJ*_*LCJ 2 c# tdd unit-testing domain-driven-design linq-to-sql

我有一个使用LINQ to SQL实现的存储库.虽然我没有数据库,但我需要进行单元测试.如何为FreezeAllAccountsForUser方法编写UT?你能用手动模拟来展示一个例子吗?

注意:域对象中使用了继承映射

注意:单元测试将使用Visual Studio Team Test完成

来自@StuperUser的评论.单元测试涉及将代码与其交互的其他对象完全隔离.这意味着如果代码失败,您可以确定失败是与测试中的代码有关.要做到这一点,你必须伪造这些对象.

     public void FreezeAllAccountsForUser(int userId)
    {
        List<DTOLayer.BankAccountDTOForStatus> bankAccountDTOList = new List<DTOLayer.BankAccountDTOForStatus>(); 

        IEnumerable<DBML_Project.BankAccount> accounts = AccountRepository.GetAllAccountsForUser(userId);
        foreach (DBML_Project.BankAccount acc in accounts)
        {
            string typeResult = Convert.ToString(acc.GetType());
            string baseValue = Convert.ToString(typeof(DBML_Project.BankAccount));

            if (String.Equals(typeResult, baseValue))
            {
                throw new Exception("Not correct derived type");
            }

            acc.Freeze();

            DTOLayer.BankAccountDTOForStatus presentAccount = new DTOLayer.BankAccountDTOForStatus();
            presentAccount.BankAccountID = acc.BankAccountID;
            presentAccount.Status = acc.Status;
            bankAccountDTOList.Add(presentAccount);

        }



        IEnumerable<System.Xml.Linq.XElement> el = bankAccountDTOList.Select(x =>
                        new System.Xml.Linq.XElement("BankAccountDTOForStatus",
                          new System.Xml.Linq.XElement("BankAccountID", x.BankAccountID),
                          new System.Xml.Linq.XElement("Status", x.Status)
                        ));

        System.Xml.Linq.XElement root = new System.Xml.Linq.XElement("root", el);


        //AccountRepository.UpdateBankAccountUsingParseXML_SP(root);
        AccountRepository.Update();

    }
Run Code Online (Sandbox Code Playgroud)

存储库层

namespace RepositoryLayer
{
public interface ILijosBankRepository
{
    System.Data.Linq.DataContext Context { get; set; }
    List<DBML_Project.BankAccount> GetAllAccountsForUser(int userID);
    void Update();

}

public class LijosSimpleBankRepository : ILijosBankRepository
{
    public System.Data.Linq.DataContext Context
    {
        get;
        set;
    }


    public List<DBML_Project.BankAccount> GetAllAccountsForUser(int userID)
    {
        IQueryable<DBML_Project.BankAccount> queryResultEntities = Context.GetTable<DBML_Project.BankAccount>().Where(p => p.AccountOwnerID == userID);
        return queryResultEntities.ToList();
    }


    public virtual void Update()
    {
        //Context.SubmitChanges();
    }

}

}
Run Code Online (Sandbox Code Playgroud)

域类

namespace DBML_Project
{

public  partial class BankAccount
{
    //Define the domain behaviors
    public virtual void Freeze()
    {
        //Do nothing
    }
}

public class FixedBankAccount : BankAccount
{

    public override void Freeze()
    {
        this.Status = "FrozenFA";
    }
}

public class SavingsBankAccount : BankAccount
{

    public override void Freeze()
    {
        this.Status = "FrozenSB";
    }
}  
}
Run Code Online (Sandbox Code Playgroud)

由LINQ to SQL自动生成的类

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.BankAccount")]
[InheritanceMapping(Code = "Fixed", Type = typeof(FixedBankAccount), IsDefault = true)]
[InheritanceMapping(Code = "Savings", Type = typeof(SavingsBankAccount))]
public partial class BankAccount : INotifyPropertyChanging, INotifyPropertyChanged
Run Code Online (Sandbox Code Playgroud)

Bar*_*low 5

简单地说,你不能.存储库实现的唯一目的是与数据库通信.因此数据库技术很重要,您应该执行集成测试.

单元测试此代码是不可能的,因为LINQ to Objects是LINQ to SQL的超集.您可能有一个绿色单元测试,并且在使用真实数据库时仍然会获得运行时异常,因为您在存储库中使用了无法转换为SQL的LINQ功能.

  • 编写单位测试会产生误报的重点是什么? (2认同)
  • 看看Moq,Rhino Mocks,FakeItEasy.您可以随时手动创建模拟.那些模拟框架使任务变得不那么冗长. (2认同)