簡體   English   中英

單元測試作業組件C#

[英]Unit Testing Job Component 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);
        }
    }
}

我知道很多人會建議使用Mocks或Stubs來代替接口,但是我對這實際上有什么好處感到有些困惑。 看起來這只會確保調用適當的方法,這讓我覺得有點空洞,並且與工作的實現相結合,是一個非常有效的測試。 最終問題變成了,你如何對沒有返回任何值的東西進行單元測試,並且真正只會導致副作用而不僅僅測試它是否以你所說的方式實現?

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

對於什么都不返回的方法,有很多方法可以驗證這一點

  1. 如果您正在使用Mocking框架,例如Moq,您可以使用Verify來確保使用適當的參數調用外部方法。
  2. 您可以使用回調來驗證傳遞給外部方法的內容(moq具有良好的回調機制)

編寫單元測試以證明您的實現正常工作。 如果您的測試代碼變得過於復雜並且變得越來越難以模擬,那么實現代碼可能會變得更加復雜和難以理解。

當你決定嘲笑依賴項時有太多的工作時,你應該重新考慮你的設計,並將其重構為一個更簡單的形式。

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

存儲庫模式是抽象數據訪問代碼的常見模式。 您還應該將電子郵件發送部分移動到另一個類並在此處使用其界面。

模擬沒有返回值的方法非常容易。 通過模擬這些方法調用,您可以證明您的類正在使用外部依賴項。您可以為參數值編寫斷言以及調用它來驗證代碼的次數。

無論如何這里是一個如何在Moq中模擬方法的例子

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

暫無
暫無

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

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