2017-07-03 44 views
0

我想在c#中編寫一個單元測試來測試那些正在進行數據庫操作(2-3個數據庫操作)的方法以及其他一些寫在裏面的邏輯它。我們如何模擬內部有很多數據庫操作的方法

private static APIResponse SubmitRequest(HttpWebRequest request, string info) 
    { 
     APIResponse responseObj = new APIResponse(); 

     WebResponse response = null; 
     // save the log into database. 
     Log.Request(request.Method + " to " + request.RequestUri.ToString() + ": " + info); 

     try 
     { 
      response = request.GetResponse(); 
     } 
     catch (WebException e) 
     { 
      var resp = (HttpWebResponse)e.Response; 

      if (resp.StatusCode == HttpStatusCode.NotModified) 
      { 
       responseObj.StatusCode = HttpStatusCode.NotModified; 
       responseObj.Headers = resp.Headers; 

       eTAG = responseObj.Headers["eTag"]; 

       // save the log into the database. 
       Log.Response("<empty>"); 

       return responseObj; 
      } 

      // save the log into the database. 
      Log.Warning(e.Message); 
      response = e.Response; 
     } 

     if (response == null) 
     { 
     Log.Response("<null>"); 
      return null; 
     } 

     StreamReader reader = new StreamReader(response.GetResponseStream()); 
     string textResponse = reader.ReadToEnd(); 

     HttpStatusCode status = ((HttpWebResponse)response).StatusCode; 
     reader.Close(); 
     response.Close(); 

     if (textResponse != null) 
     { 
      textResponse = textResponse.Trim(); 
     } 
     // save the log into the database. 
     Log.Response(textResponse.Length == 0 ? "<empty>" : textResponse); 

     if (textResponse.Length == 0) 
      return null; 

     responseObj.Headers = response.Headers; 
     responseObj.Message = textResponse; 
     responseObj.StatusCode = status; 

     eTAG = responseObj.Headers["eTag"]; 

     return responseObj; 
} 

正如你可以在摘要中看到,我們在代碼的不同時間之間保存記錄到數據庫中。我們如何模擬/停止這些日誌來保存。

public static void Request(string text) 
    { 
     -- code to save the code in db. 
    } 

public static void Response(string text) 
    { 
     -- code to save the code in db. 
    } 

我們怎麼能實現呢?有人猜測任何人嗎?

+0

能如你所願方法的代碼添加到單元測試請。 – Scrobi

+1

通常,您要提取將數據庫調用爲依賴項的類並通過構造函數注入。這樣你就可以實例化一個測試版/模擬的類,並將其傳遞到你想測試的類 – Stuart

+0

這是一個非常廣泛的問題。你可以模擬數據層本身並返回虛擬數據,或者你可以模擬IQueryable(如果你使用任何),並使用例如字典而不是實際的表。如果您使用EF,則可以模擬EF上下文。您可以使用SQLite內存數據庫而不是實際的數據庫。 EF Core甚至只有用於測試的內存數據庫 –

回答

1

所以使用Moq,你是測試和你想測試的類可以看起來像這樣。

public class ClassToTest 
{ 
    IDataAccessService _dataAccessService; 
    public ClassTotest(IDataAccessService dataAccessService) 
    { 
     _dataAccessService = dataAccessService; 
    } 
    public int SomeMethodWeWantToTest() 
    { 
     // Do Something. 
    } 
} 

這裏我們使用依賴注入來注入DAL。這種方式在測試時間,我們可以通過模擬。

public class ConcreteDataAccessService : IDataAccessService 
{ 
    public List<int> GetSomeNumbersFromTheDatabase() 
    { 
     // Call db. 
     // Get some numbers. 
     // Return a list of them. 
    } 
} 

public IDataAccessService 
{ 
    List<int> GetSomeNumbersFromTheDatabase(); 
} 

這裏我們展示一個代表我們DAL的接口。我們有一個實現接口的具體實現IDataAccessService這個具體的實現是我們可以在非測試運行時調用的。

[TestClass] 
public class ClassToTestTests 
{ 
    [TestMethod] 
    public void SomeMethodWeWantToTest_ShouldAddUpAllNumbersFromDatabaseCorrectly() 
    { 
      Mock<IDataAccessService> dataAccessServiceMock = new Mock<IDataAccessService>(); 
      dataAccessService.Setup(x=>x.GetSomeNumbersFromTheDatabase()).Returns(new List<int>{1,2,3,4,5}); 
      ClassToTest classToTest = new ClassToTest(dataAccessService.Object()); 
      int expected = 15; 
      Assert.AreEqual(expected, classToTest.SomeMethodWeWantToTest()); 
    } 
} 

測試類使用起訂量,嘲弄的框架,嘲笑DataAccessService並建立我們希望,當我們調用的方法GetSomeNumbersFromTheDatabase返回。

然後,我們實例化要測試的類,並將模擬的DataAccessService傳遞給類構造函數。

通過這種方式,我們可以測試ClassToTest.SomeMethodWeWantToTest()的功能,而不會觸及實際的數據庫。

注意該代碼不會編譯或檢查。這是關於如何做,非常基本的DI和測試的粗略概述。但你沒有提供任何代碼在你的問題......

+0

謝謝Stuart,我重構了現有的代碼,併爲此寫了一些測試。但缺陷是解決方案內部沒有數據訪問層,因此難以實現..在這種情況下,任何幫助將不勝感激。 –

+0

我會在Log類中創建一個包裝,並在其上放置一個接口,僅使用您提供的2個方法。然後將它傳遞給你已經顯示方法的類的構造函數。然後調用接口上的方法。現在在測試時你可以模擬接口。 – Stuart

+0

是的,但是我的目標不僅僅是模擬Log.Response或Log.Request,而且也是一個包含這些日誌保存方法的整體方法「SubmitRequest」。 –

相關問題