背景
本文假设你对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 WhatIsStubTest11 {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 StubIDependencyService22 {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 WhatIsStubTest12 {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 ShimDependencyService26 {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 WhatIsStubTest11 {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 MockCreateMockDependencyService()24 {25 return new Mock ();26 }27 }28 }
备注:mock是一种功能丰富的stub。
备注
我目前只使用MS的Fake,感觉够了。