单元测试-测试替身

在讲Test Double以前,得先上搞清楚另外两个

SUT:System Under Test/Software Under Test 【待测程式】,在Unit Test角度下待测程式会是method

DOC:Depended-on Component【相依元件】,例如:成立订单函数,如果订单失败异常会写入log,log函数就是成立订单函数的DOC

在实务上笔者在写单元测试的时候,因为SUT会去呼叫其他的物件也会呈现出SUT依赖DOC,
在测试SUT势必会有DOC存在,搞得测试很複杂。

目前测试替身有五种Dummy Object、Test Stub、Test Spy、Fake Object与Mock Object
笔者目前是常用到Stub、Mock、Fake Object。

Dummy Objects用法:测试中必续传入的物件,实际上这些物件根本不会用到,只是为了能够调用背侧物件而必须传入的一个东西【目前没用到】。

Stub用法:回传固定的值。

    public class StubUserRepository : IUserRepository    {        public string GetUserRole(string username)        {            return "administrator";        }        public List<User> GetAllUsers()        {            return new List<User>()            {                new User{ Role = "administrator", Name = "admin"},            };        }    }    public interface IUserRepository    {        string GetUserRole(string username);    }    public class User    {        public string Name { get; set; }        public string Role { get; set; }    }

Fake用法:接近提供原始物件较简单实作方式。

    public class FakeUserRepository : IUserRepository    {        public string GetUserRole(string username)        {            if (username == "admin")                return "administrator";            else                return "contributor";        }    }    public interface IUserRepository    {        string GetUserRole(string username);    }

Spy用法:把spy想成是一个偷偷纪录呼叫过程的Stub,宣告被spy的物件,某个函式被呼叫的时候回传某个值。

    public class SpyUserStore : IUserRepository    {        private static int Counter { get; set; }        public SpyUserStore()        {            Counter = 0;        }        public string GetUserRole(string username)        {            if (Counter >= 1)                throw new Exception("Function called more than once");            Counter++;            if (username == "admin")                return "administrator";            else                return "contributor";        }    }

Mock用法:用动态程式方式、提供类似Dummy,Stub,Spy功能

   var _memberRepository = Substitute.For<IMemberRepository>();   var _memberService = new MemberService(_memberRepository);   var _setReturnMember = new Member()        {           UserId = "test001",           Password = "test001",           Name = "test",           Email = "abc@gmail.com"        };   _memberRepository.GetByMember(userid,password).Returns(_setReturnMember);

最后总结一下,测试替身可以解决单元测试的那些问题?

测试替身是为了解决不用真的使用DOC可以提升测试执行速度,避免速度太慢

另外其实在真的写测试,也不用太在意你是用哪一个测试替身...

参考来源

搞笑谈软工-测试替身jyt0532's Blog-测试替身

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章