[英]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
類時將其注入。 為了進行單元測試,請在單元測試中模擬依賴項,以確保它以預期的方式調用已定義的依賴項合同。
通常,這意味着:
最終結果是,您的代碼將進行如下轉換:
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.