2017-07-03 50 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”。 –

相关问题