【Unit Test】Stub破除依賴(四) - 抽取和重寫範例一
/
0 Comments
前言:
相信很多人都遇過Legancy Code,改沒有留下測試的Legancy Code最怕的就是改了東卻壞了西卻還不知道,為了避免類似問題,我們可以嘗試在Legancy Code中加入單元測試。但是事情往往沒那麼順利,很多專案都外部依賴的很頻繁,想重構切出介面等可能工程浩大,要想在動到最少程式碼的情況下去加入單元測試,"抽取和重寫(extract and override)"會是個有用的技術。使用被測試類別中的一個virtual方法做為工廠方法,在MemberService的子類別複寫這個虛擬方法,產生出你需要的接口。在接口注入你準備好的Stub物件,之後測試就以子類別來進行。
程式碼如下:
//原程式碼 public class MemberRepository { public string GetID(string name) { return "Original"; } } public class MemberService { public string GetMemberID(string name) { MemberRepository memberrepository = new MemberRepository(); return memberrepository.GetID(name); } } //重構後 public class MemberRepository : IMemberRepository { public string GetID(string name) { return "Original"; } } public interface IMemberRepository { string GetID(string name); } public class MemberService { protected virtual IMemberRepository GetRepository() { return new MemberRepository(); } //被測試的方法 public string GetMemberID(string name) { return GetRepository().GetID(name); } } public class TestableMemberService : MemberService { private IMemberRepository _IMemberRepository; public TestableMemberService(IMemberRepository memberRepository) { this._IMemberRepository = memberRepository; } protected override IMemberRepository GetRepository() { return this._IMemberRepository; } }
測試程式碼 :
//Stub public class FakeMemberRepository : IMemberRepository { public string returnID { get; set; } public string GetID(string name) { return returnID; } } [TestMethod()] public void GetMemberID_Test() { //arrange var name = "Tom"; var expected = "321"; var stub = new FakeMemberRepository(); stub.returnID = expected; TestableMemberService sut = new TestableMemberService(stub); //act var actual = sut.GetMemberID(name); //assert Assert.AreEqual(expected, actual); }