赞
踩
Analyze类会检查filename的长度,如果小于8,我们就会使用一个实现IWebService的类来记录错误.
我们需要给Analyze方法写单元测试。
- 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 Analyze(string fileName)
- {
- if (fileName.Length < 8)
- {
- try
- {
- service.LogError("the file name is to short" + fileName);
- }
- catch (Exception e)
- {
- email.SendEmail("From@test.com", "To@test.com", "IWebServiceFailed", e.Message);
- }
- }
- }
- }
如果你想学习性能测试,我这边给你推荐一套视频,这个视频可以说是B站播放全网第一的自动化测试教程,同时在线人数到达1000人,并且还有笔记可以领取及各路大神技术交流:798478386
测试用例一:
fileName= "c:\test\test.txt" (长度大于8),
期待测试结果: 不会发邮件
测试用例二:
fileName="c:\",(长度小于8), 并且记log失败 。
期待测试结果: 发邮件
如果给Analyze方法写单元测试,为了实现测试用例二。 这时候我们就会碰到两个问题。
第一: 我们无法控制让Service对象记log时抛出异常. 因为Serveice对象我们无法控制
第二: 我们无法判断,Email对象是否发送了Email, (我们不能去Outlook查看收到邮件没有,这样就不是自动化了)
对于LogAnalyzer对象来说, Service和Email就是两个外部依赖对象. 我们需要自己写Stub和Mock来模拟这两个外部依赖对象。这样我们才能控制他们。
我们在测试的代码中新建StubWebService和MockEmailService.这两个class分别实现了IWebService和IEmailService.
- public class StubWebService : IWebService
- {
- public void LogError(string message)
- {
- throw new Exception("StubWebService throw exception");
- }
- }
-
- public class MockEmailService : IEmailService
- {
- public string To;
- public string From;
- public string Subject;
- public string Message;
-
- public void SendEmail(string to, string from, string subject, string message)
- {
- To = to;
- From = from;
- Subject = subject;
- Message = message;
- }
- }
工作流程图如下
最后我们来看看我们的测试代码,
我们把StubWebService和MockEmailService两个类的实例注入到产品代码中。(因为多态特性嘛)。
通过控制StubWebService中的LogError方法,抛出一个异常。
然后判断MockEmailService中的SendEmail方法有没有被调用. 被调用了说明发送了Email(我们不需要真的收到一封邮件,因为SendEmail功能是IEmailService实现的,)
- [TestMethod]
- public void TestMethod1()
- {
- StubWebService stubWebService = new StubWebService();
- MockEmailService mockEmailSender = new MockEmailService();
-
- LogAnalyzer log = new LogAnalyzer();
- log.Emailservice = mockEmailSender;
- log.WebService = stubWebService;
-
- // Act
- string tooShortFileName = "1.txt";
- log.Analyze(tooShortFileName);
-
- // Assert
- Assert.AreEqual("to@test.com", mockEmailSender.To);
- Assert.AreEqual("from@test.com", mockEmailSender.From);
- Assert.AreEqual("WebSerive log error", mockEmailSender.Subject);
- }
从上面的例子我们可以看出, Stub和Mock都是模拟外部依赖,以便我们能控制。
Stub是完全模拟一个外部依赖, 而Mock用来判断测试通过还是失败
如果产品代码是下面那样,你就没办法测试了。 因为WebService和EmailService两个类没有继承接口。我们无法把StubWebService和MockEmailService两个类注入到产品代码。
- public class LogAnalyzer
- {
- private WebService webService;
- private EmailService emailService;
-
- public WebService WebService
- {
- get { return webService; }
- set { webService = value; }
- }
-
- public EmailService Emailservice
- {
- get { return emailService; }
- set { emailService = value; }
- }
-
- public void Analyze(string fileName)
- {
- if (fileName.Length < 8)
- {
- try
- {
- WebService.LogError("Filename too short:" + fileName);
- }
- catch (Exception e)
- {
- Emailservice.SendEmail("to@test.com", "from@test.com", "WebSerive log error", e.Message);
- }
- }
- }
- }
其实我们没有必要自己写MockEmailService方法。 已经有现成的Mock框架可以用了, .NET中有Rhino Mock 和 Moq, 这两个框架比较好用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。