【Unit Test】使用Stub破除依賴(三)

/
0 Comments

前言:

這篇說明的是 "在方法被呼叫前注入偽對象",配合使用工廠模式來達成。


延續上一篇的例子,只是這次不用在MemberService的建構子傳入參數,而是透過工廠模式來返回Stub物件(實作IMemberRepository的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 class MemberService
{
 private IMemberRepository _IMemberRepository;

 public MemberService()
 {
  //呼叫工廠
  this._IMemberRepository = MemberRepositoryFactory.Create();
 }

 //被測試的方法
 public string GetMemberID(string name)
 {
  return this._IMemberRepository.GetID(name);
 }
}

public interface IMemberRepository
{
 string GetID(string name);
}

//工廠方法
public class MemberRepositoryFactory
{
 private static IMemberRepository repository = null;

 public static IMemberRepository Create()
 {
  if (repository != null)
  {
   return repository;
  }
  return new MemberRepository();
 }

 public static void SetRepository(IMemberRepository mrp)
 {
  repository = mrp;
 }
}


測試程式碼 :
//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 imr = new FakeMemberRepository();
 imr.returnID = expected;
 MemberRepositoryFactory.SetRepository(imr);
 MemberService sut = new MemberService();

 //act
 var actual = sut.GetMemberID(name);

 //assert
 Assert.AreEqual(expected, actual);
}

結語:

和之前做法不同的是,這次是將接口加在工廠類別中,使用這種技術的測試程式碼可讀性較佳,每個類別的職責清晰。


You may also like

沒有留言: