TDD:什么是桩(stub)和模拟(mock)?
背景
本文假设你对TDD、Stub和Mock已经有了初步的认识,本文简单解释一下stub和mock的区别和使用场景,先看看他们之间的关系:
由上图可以知道mock框架可以非常容易的开发stub和mock,但是stub框架想要提高mock机制就要靠自己扩展了。
Stub
stub存在的意图是为了让测试对象可以正常的执行,其实现一般会硬编码一些输入和输出,下面的代码使用了MS自带的Fake和Shim来实现stub。
Fake实现
1 using System; 2 using Microsoft.VisualStudio.TestTools.UnitTesting; 3 4 using TDDStudy.Library.WhatIsStub; 5 using TDDStudy.Library.WhatIsStub.Fakes; 6 7 namespace TDDStudy.WhatIsStub 8 { 9 [TestClass] 10 public class WhatIsStubTest 11 { 12 [TestMethod] 13 public void Stub_Test() 14 { 15 var domainService = new DomainService(CreateStubDependencyService()); 16 domainService.Task(); 17 } 18 19 private IDependencyService CreateStubDependencyService() 20 { 21 return new StubIDependencyService 22 { 23 OtherTask = () => { } 24 }; 25 } 26 } 27 }
Shim实现
1 using System; 2 using Microsoft.VisualStudio.TestTools.UnitTesting; 3 using Microsoft.QualityTools.Testing.Fakes; 4 5 using TDDStudy.Library.WhatIsShim; 6 using TDDStudy.Library.WhatIsShim.Fakes; 7 8 namespace TDDStudy.WhatIsShim 9 { 10 [TestClass] 11 public class WhatIsStubTest 12 { 13 [TestMethod] 14 public void Shim_Test() 15 { 16 using (ShimsContext.Create()) 17 { 18 var domainService = new DomainService(CreateShimDependencyService()); 19 domainService.Task(); 20 } 21 } 22 23 private DependencyService CreateShimDependencyService() 24 { 25 return new ShimDependencyService 26 { 27 OtherTask = () => { } 28 }; 29 } 30 } 31 }
备注:微软的Fake适合接口、保护虚方法的类,Shim适合其它类(封闭的、非虚的)。
Mock
mock除了保证stub的功能之外,还可深入的模拟对象之间的交互方式,如:调用了几次、在某种情况下是否会抛出异常,下面的代码使用了moq来实现mock。
moq实现
1 using System; 2 using Microsoft.VisualStudio.TestTools.UnitTesting; 3 4 using Moq; 5 using TDDStudy.Library.WhatIsMock; 6 7 namespace TDDStudy.WhatIsMock 8 { 9 [TestClass] 10 public class WhatIsStubTest 11 { 12 [TestMethod] 13 public void Mock_Test() 14 { 15 var mock = CreateMockDependencyService(); 16 17 var domainService = new DomainService(mock.Object); 18 domainService.Task(); 19 20 mock.Verify(x => x.OtherTask(), Times.AtMostOnce); 21 } 22 23 private Mock<IDependencyService> CreateMockDependencyService() 24 { 25 return new Mock<IDependencyService>(); 26 } 27 } 28 }
备注:mock是一种功能丰富的stub。
备注
我目前只使用MS的Fake,感觉够了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
2013-02-19 技术人生:人的差别在于业余时间