簡體   English   中英

與數據庫通信的單元測試類

[英]Unit Testing class which communicates with a database

好的,假設我有一個控制我的數據層的類和一個執行工作的類。

class MyData
{
    public DataTable GetMyData()
    {
         return Query.MyDataBase.ResultDT();
    }
}

class MyWork
{
    public int DoWork()
    {
        MyData Data = new MyData();
        DataTable DT = Data.GetMyData();
        return DT.Rows.Count;
    }
}

如何在不訪問數據庫的情況下使用單元測試來測試DoWork方法。

[TestMethod()]
public void TestMyWork()
{
    MyWork work = new MyWork();
    int result = work.DoWork();
    Assert.AreEqual(1, result);
}

使MyData類成為依賴項參數,並在構造MyWork類時將其注入。 為了進行單元測試,請在單元測試中模擬依賴項,以確保它以預期的方式調用已定義的依賴項合同。

通常,這意味着:

  • 定義依賴項的接口,即IMyData
  • 構造函數簽名應使用接口類型,而不是具體類型。

最終結果是,您的代碼將進行如下轉換:

interface IMyData
{
    DataTable GetMyData();
}

class MyData : IMyData
{
    public DataTable GetMyData()
    {
         return Query.MyDataBase.ResultDT();
    }
}

class MyWork
{
    private IMyData _myData;

    public MyWork(IMyData myData)
    {
        _myData = myData;
    }

    public int DoWork()
    {
        DataTable DT = _myData.GetMyData();
        return DT.Rows.Count;
    }
}

進一步,您應該檢查SOLID設計原則,因為這種類型的設計說明了它們為什么存在。

有關Wikipedia的更多信息:SOLID(面向對象設計)

編輯:

然后,您的單元測試將類似於(假設您使用的是Moq模擬框架):

[TestMethod()]
public void TestMyWork()
{
    var mockMyData = Mock<IMyData>();
    mockMyData.Setup(x => x.GetMyData()).Returns(new DataTable());

    MyWork work = new MyWork(mockMyData);
    int result = work.DoWork();
    Assert.AreEqual(1, result);
}

..但是在現實世界中,您很有可能按照如下所示使用真實的MyData實例實例化MyWork (除非您使用的是Dependency Injection框架,例如MEF或Unity):

var myWork = new MyWork(new MyData());

首先,遵循@toadflakz建議並將MyData注入MyWork的構造函數中。

然后,使用一些ORM將數據從db映射到對象。 不要使用DataTable

為了使DoWork易於測試,請考慮將其重構為一個純函數

public int DoWork(DataTable dt)
{
    // make some complex calculations on dt
}

這樣, DoWork的結果僅取決於輸入參數,這使得測試非常容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM