单元测试没有数据库:LINQ到SQL(Unit Testing without Database:

2019-06-26 02:02发布

我使用LINQ to SQL存储库来实现。 我需要做单元测试,虽然我没有一个数据库。 我怎么能写FreezeAllAccountsForUser方法UT? 能否请您使用手动嘲讽显示一个例子吗?

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

注:单元测试是使用Visual Studio团队测试完成

从@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();

    }

库层

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();
    }

}

}

域类

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";
    }
}  
}

自动生成的类通过的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

Answer 1:

资源库的责任是坚持域对象并获取他们的请求。 也就是说,它的工作是把一个物体和反序列化/从某种形式的持久存储的序列化。

所以对于存储库的测试需要测试对在这种情况下,DB实际存储。 即这些都是集成测试 - 测试您的类与外部数据库集成。

一旦你有了这个钉,客户端/应用程序的其它部分没有反对真正的DB工作。 他们可以嘲笑资源库,并且具有快速的单元测试。 你可以假设GetAccount工作,因为集成测试通过。

更多详细信息:通过在Repository对象传递的构造函数或方法ARG,你打开门传递一个假的或者是模拟。 因此,现在的服务测试可没有一个真正运行的仓库>>没有DB-进入>>快速测试。

public void FreezeAllAccountsForUser(int userId, ILijosBankRepository accountRepository)
{
  // your code as before
}

test ()
{  var mockRepository = new Mock<ILijosBankRepository>();
    var service = // create object containing FreezeAllAccounts...

    service.FreezeAllAccounts(SOME_USER_ID, mockRepository);

    mock.Verify(r => r.GetAllAccountsForUser(SOME_USER_ID);
    mock.Verify(r => r.Update());
}


Answer 2:

简单地说,你不能。 库实现的唯一目的是谈论到数据库。 因此,数据库技术此事做,你应该进行集成测试。

单元测试这个代码是不可能的,因为LINQ到对象是LINQ to SQL的一个超集。 你可能有一个绿色的单元测试和使用真实分贝时,因为你在你的仓库不能转换成SQL使用LINQ的特征仍然得到了运行时异常。



Answer 3:

您可以使用您的DataContext IDbSet接口,并提取了您的DataContext类的接口。 对接口编程的关键是创建单元测试代码。

你想为这些LINQ查询创建单元测试的原因是有逻辑询问单元测试。 集成测试都受到各种假阴性。 在正确的状态不是分贝,在同一时间运行,其他集成测试等其他查询这是非常困难的隔离分贝不够好,可靠的集成测试。 这就是为什么集成测试往往都被忽略。 如果非要挑一个,我想单元测试...



文章来源: Unit Testing without Database: Linq to SQL