レガシー プロジェクトをテスト対象にしようとしています。コードは一般的にテストできるように書かれていますが、サードパーティの依存関係の一部はそうではありませんでした。次のような単体テストの方法を頭に入れようとしています。
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);
}
}
}
インターフェイスの代わりにモックまたはスタブを使用して渡すことを提案する人が多いことは理解していますが、これが実際にどのように役立つかについては少し混乱しています。これは、適切なメソッドが呼び出されることを保証するだけのようですが、これはやや空虚であり、ジョブの実装とあまりにも結びつきすぎて、本当に有効なテストにはなりません。最終的に問題になるのは、値を返さず、実際に副作用を引き起こすだけのものを、あなたが言うように実装されていることをテストするだけでなく、どのように単体テストするのですか?