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