我是靠谱客的博主 朴实缘分,最近开发中收集的这篇文章主要介绍单元测试的mock和stubStub 和Mock 的区别,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

   微笑还是一个转载:http://www.cnblogs.com/TankXiao/archive/2012/03/06/2366073.html

在做单元测试的时候,我们会发现我们要测试的方法会引用很多外部依赖的对象,比如:(发送邮件网络通讯记录Log文件系统 之类的)。 而我们没法控制这些外部依赖的对象。  为了解决这个问题,我们需要用到Stub和Mock来模拟这些外部依赖的对象,从而控制它们


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);
}
}
}
}

测试用例一: 

fileName= "c:testtest.txt" (长度大于8),      

期待测试结果: 不会发邮件

测试用例二: 

fileName="c:",(长度小于8),  并且记log失败 。  

期待测试结果: 发邮件

 

如果给Analyze方法写单元测试,为了实现测试用例二。  这时候我们就会碰到两个问题。

第一: 我们无法控制让Service对象记log时抛出异常. 因为Serveice对象我们无法控制

第二: 我们无法判断,Email对象是否发送了Email, (我们不能去Outlook查看收到邮件没有,这样就不是自动化了)


对于LogAnalyzer对象来说, Service和Email就是两个外部依赖对象. 我们需要自己写Stub和Mock来模拟这两个外部依赖对象。这样我们才能控制他们。

我们在测试的代码中新建StubWebServiceMockEmailService.这两个class分别实现了IWebServiceIEmailService

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);
}
}
}
}



最后

以上就是朴实缘分为你收集整理的单元测试的mock和stubStub 和Mock 的区别的全部内容,希望文章能够帮你解决单元测试的mock和stubStub 和Mock 的区别所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部