簡體   English   中英

NoSQL - 如何模擬數據庫進行單元測試?

[英]NoSQL - How to mock database for unit testing?

我正在研究 NoSQL 數據庫並且有一個關於單元測試的問題。 對業務邏輯進行單元測試的合適方法是什么? 如何模擬 NoSQL 數據庫?

您的業務邏輯不應該直接接觸數據庫,而是通過數據庫訪問層 go。 這使您可以模擬該中間層以進行單元測試。 為此,您可以使用依賴注入和 mocking。有些框架可以幫助您完成這兩件事,但您也可以手動完成。 這是一個例子:

假設我們有一個 DAL:

public class DBDataProvider: IDataProvider
{
    public string getData()
    {
         //SQL to get data from actual database.
    }
}

如您所見,這實現了一個為您的業務層提供數據的接口。 它可能看起來像這樣:

public Interface IDataProvider
{
     String getData();
}

您的業務層可能看起來像這樣:

public BusinessClass
{
    private IDataProvider dataProvider;

    public BusinessClass()
    {
        dataProvider = new DBDataProvider();
    }

    public BusinessClass(IDataProvider provider)
    {
        dataProvider = provider;
    }

    public void doBusinessStuff()
    {
        dataProvider.getData(); 
        //Do something with data.
    }

}

所以現在在您的生產代碼中,您將使用默認構造函數創建您的業務 class,這將自動使您的 class 連接到數據庫。 但是,請注意,我們可以使用指定的 IDataProvider 創建 BusinessClass。 因此,您可以制作一個僅用於測試的“假”數據提供者:

public class MockDataProvider: IDataProvider
{
    public string getData()
    {
         //return some expected result that you can control, without doing a DB call.
    }
}

現在在您的測試中,您可以創建一個新的 MockDataProvider,並將其傳遞到 BusinessClass 的構造函數中。 您的業務 class 現在將使用您的模擬數據提供程序,而不是真正的數據庫。

在這里,我手工完成了所有操作,但它讓您了解這是如何工作的。 在現實生活中,您可以使用 mocking 和依賴注入框架為您編寫一堆代碼。

與模擬任何依賴項的方式相同。 編寫一個漂亮、整潔的合約,可以從中抽象出實現細節,然后模擬該合約。 通常這是通過使用數據訪問層作為合同來完成的。
在不深入了解實際實現細節的情況下,假設您在要測試的方法中有一個查詢:(注意,我從 ravenDB 示例中復制了這段代碼,但我對 ravenDB 的了解為 0,因此它甚至可能無法編譯)

public void SomeMethod()
{
    var name = "Hello";
    var motto = "World";                       
    using (var docStore = new DocumentStore("localhost", 8080).Initialize())
    using (var session = documentStore.OpenSession()){
        session.Store(new Company { Name = name, Motto = motto });;
        session.SaveChanges();
    }
}

這將很難模擬/測試,因為它需要 8080 本地主機上的數據庫。現在,如果您將此邏輯分離到另一個 class 中:

public class AwesomeDAL
    public virtual void AddCompany(string name, string motto){
        using (var docStore = new DocumentStore("localhost", 8080).Initialize())
        using (var session = documentStore.OpenSession()){
            session.Store(new Company { Name = name, Motto = motto });;
            session.SaveChanges();
        }
}

並允許注入依賴項 (AwesomeDal):

public class ClassBeingTested
{
    public AwesomeDal DAL { get; set; }
    public ClassBeingTested() : this(new AwesomeDal()){}
    public ClassBeingTested(AwesomeDal dal)
    {
       this.DAL = dal;
    }

    public void SomeMethod()
    {
        var name = "Hello";
        var motto = "World";                       
        this.DAL.AddCompany(name, motto);
    }
}

您現在可以單獨測試 BL 代碼。 或者你可以模擬數據庫異常,或者任何你需要測試的東西,因為你的數據訪問層是抽象的,它的實現很容易用Moq或 RhinoMocks 這樣的框架模擬

除了已經發布的(正確的)答案之外,讓我提出一個替代解決方案:使用真實的開發數據庫。 如果您直接對其進行測試,沒有什么比真實的模擬更逼真了。 至少你知道你的代碼會實際運行。

如果您可以輕松地抽象出您的數據庫,我建議您這樣做。

暫無
暫無

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

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