本文演示同时使用桩对象和模拟对象。
当文件名太短时,LogAnalyzer发送错误消息给Web服务器。Web服务器出错时,发送邮件给管理员。
有上述业务可知,LogAnalyzer有两个外部依赖:Web服务和邮件服务。现在测试LogAnalyzer在Web服务抛出异常时正确调用了邮件服务。
桩对象:使Web服务抛出的异常,确保测试正确运行。
模拟对象:模拟邮件服务,验证是否向邮件服务传入正确的参数。
1.桩对象
Web服务桩对象模拟一个Web服务器异常,使得被测类发送邮件给管理员。
public interface IwebService
{
void LogError(string message);
}
public class StubService : IwebService
{
public Exception ToThrow;
public void LogError(string message)
{
if (ToThrow != null)
throw ToThrow;
}
}
2.模拟对象
电子邮件模拟对象检查邮件是否正确发送。
public interface IEmailService
{
void SendEmail(string to, string subject, string body);
}
public class MockEmailService: IEmailService
{
public string To;
public string Subject;
public string Body;
public void SendEmail(string to, string subject, string body)
{
To = to;
Subject = subject;
Body = body;
}
}
3.被测对象
public class LogAnalyzer
{
private IwebService service;
private IEmailService email;
public IwebService Service
{
get { return service; }
set { service = value; }
}
public IEmailService Email
{
get { return email; }
set { email = value; }
}
public void Analyzer(string fileName)
{
if (fileName.Length < 6)
{
try
{
service.LogError("Filename too short:" + fileName);
}
catch (Exception e)
{
email.SendEmail("April","WebService error",e.Message);
}
}
}
}
4.测试类
[Test]
public void Analyze_TooShortFileName_CallsWebService()
{
StubService stubService = new StubService();
stubService.ToThrow = new Exception("Fack exception");
MockEmailService mockEmail = new MockEmailService();
LogAnalyzer log = new LogAnalyzer();
log.Service = stubService;
log.Email = mockEmail;
log.Analyzer("s.log");
Assert.AreEqual("April", mockEmail.To);
Assert.AreEqual("Fack exception", mockEmail.Body);
Assert.AreEqual("WebService error", mockEmail.Subject);
}