2013-05-01 68 views
3

我正在嘗試將一個遺留項目置於測試中。代碼的編寫方式通常是可測試的,但某些第三方依賴關係不是。我試圖總結我的周圍,看起來如何進行單元測試是這樣的頭:單元測試作業組件C#

class InsightEmailJob : NHibernateJob 
{ 
    public IInsightEmailService InsightEmailService { get; set; } 
    public IReportService ReportService { get; set; } 
    public ITemplatedNotifier TemplatedNotifier { get; set; } 
    public string ReplyEmail { get; set; } 
    public string ReplyName { get; set; } 

    public InsightEmailJob(ISession session, 
     ILog log, 
     IInsightEmailService insightEmailService, 
     IReportService reportService, 
     ITemplatedNotifier templatedNotifier, 
     SystemReplyEmailSpec systemReplyEmailSpec) 
     : base(session, log) 
    { 
     InsightEmailService = insightEmailService; 
     ReportService = reportService; 
     TemplatedNotifier = templatedNotifier; 
     ReplyEmail = systemReplyEmailSpec.ReplyEmail; 
     ReplyName = systemReplyEmailSpec.ReplyName; 
    } 

    public int AccountID{ get; set; } 
    private Account mAccount; 

    public Account Account 
    { 
     get 
     { 
      if (this.mAccount == null) 
      { 
       mAccount = this.InsightEmailService.Get<Account>(AccountID); 
      } 
      return mAccount; 
     } 
    } 


    protected override void DoWork(JobExecutionContext context) 
    { 
     var insightEmail = InsightEmailService.FindAndIncrementEmailForAccount(Account); 
     var report = ReportService.LoadMultiReportByName(insightEmail.ReportName); 
     var reportData = ReportService.Execute(report, new ParameterValuesDictionary(Account, DateTime.Now.AddDays(-7), DateTime.Now, 0)); 
     var templateData = new Hashtable {{"data", reportData}, {"account", Account}}; 
     foreach (var u in Account.Users.Where(x => x.Notify)) 
     { 
      TemplatedNotifier.Send(u.UserName, ReplyName, ReplyEmail, insightEmail.TemplateName, templateData); 
     } 
    } 
} 

據我瞭解,很多人會建議使用嘲笑或存根在傳遞,而不是接口,但是我有點困惑,這實際上是有益的。看起來,這樣做只會確保調用適當的方法,這讓我覺得有些空洞,並且與作業的實現相關聯成爲一個非常有效的測試。最終問題就變成了,你如何單元測試不返回值的東西,而只是在沒有按照你說的方式進行測試的情況下進行測試纔會產生副作用?

回答

0

當你做單元測試時,你只是測試單元。它意味着在給定的外部依賴關係下,單元如何(例如調用其他服務的方法)。因此,如果您的測試代碼的行爲正確,您需要查看各種外部依賴條件。

對方法,返回什麼有多種方法,如果你使用的是模擬框架來驗證這個

  1. ,比方說起訂量,您可以使用驗證,以確保外部方法與適當的呼叫參數。
  2. 您可以驗證什麼是傳遞到使用回調(MOQ具有良好的回撥機制)的外部方法
0

單位編寫測試來證明你實現正常工作。如果你的測試代碼變得越來越複雜,而且事情變得越來越難以模擬,那麼實現代碼可能變得越來越複雜和難以理解。

當你決定在嘲笑依賴關係中有太多的工作時,你應該重新考慮你的設計,並且旨在將它重構爲一個更簡單的表單。

只要看看你的構造函數,我們就可以看到它可能做了太多的工作。你有6個依賴關係,你將不得不模擬所有這些來編寫有效的單元測試。我不認爲你有足夠的抽象,因爲你必須處理NHibernate會話,一些報告服務和發送電子郵件。

Repository Pattern是抽象數據訪問代碼的常見模式。您還應該將電子郵件發送部分移至其他課程並在此處使用其界面。

模擬沒有返回值的方法很容易。通過嘲笑這些方法調用,您可以證明您的類正確使用外部依賴關係。您可以爲參數值編寫斷言,以及調用驗證代碼的次數。

反正這裏有一個如何在Moq

insightEmailService.Setup(mock => mock.FindAndIncrementEmailForAccount(It.IsAny<Account>())) 
        .Verifiable(); 
+0

嘲笑的方法一個例子,我不知道怎樣添加另一個抽象這裏是要減少複雜性。發送*的電子郵件已被抽象爲已實現接口的類,我*已*使用接口。 IInsightEmailService是加載InsightEmails的存儲庫。我可以將SystemReplyEmailSpec推入通知程序,並且這會將相關性降低到5,但我沒有看到勝利。爲什麼要把另一個類放到這個地方(即相同的東西)比使用已經存在的代碼更好? – 2013-05-01 21:21:53