簡體   English   中英

如何在類中為方法編寫單元測試,但不使用C#中的類調用構造函數

[英]How to write unit test for a method in a class but not call the constructor i the class in C#

我想對class A MethodA進行單元測試。 但是,在構造A時,我並不是真的想調用MethodB ,因為要花很多時間來處理。

有什么辦法可以解決嗎? 必須先調用MethodB ,這樣我才能將其移出ctor(它會初始化listAlistBlistC字段)。

我不知道該如何使用模擬框架。

public Class A {

  List<int> listA;
  List<int> listB;
  List<int> listC;


  public A()
  {     
     MethodB();    // Long processing.
  }


  public List<int> GetA()
  {
      return listA;
  } 

  public List<int> GetB()
  {
      return listB;
  } 

  public List<int> GetC()
  {
      return listC;
  } 

  private void MethodB()
  {
      // Expensive initialization of list fields.
  }

  public bool MethodA(customerCollection foo)
  {
        for (int i = 0; i < customerCollection .Count; i++)
        {
            if (customerCollection[i].Name == "Something")
            {
                return true;
            }
        }

      return false;

  }
}

據我所知,您的MethodA不需要A實例即可起作用,因此您可以將其更改為static並在沒有A實例的情況下對其進行測試。 但是請注意,從OOP的角度來看,此方法在A類(單一職責原則)中沒有位置,因此您需要一些重構。

盡管很清楚MethodA可以是static ,但它不使用任何我建議使用其他方法的class字段,因為問題是用moq控制反轉標簽標記的。 進行一些重新設計,您可以將其存檔。例如,可以通過IRepository接口公開列表,然后可以利用IoC原理在單元測試中啟用模擬。 像這樣:

public interface IRepository
{
    void Init();
    IList<int> Get();
}

public Class A 
{    
  IRepository _aRepository;
  IRepository _bRepository;
  IRepository _cRepository;

  public A(IRepository aRepository, IRepository bRepository, IRepository bRepository)
  {
    _aRepository = aRepository;
    _bRepository = bRepository;
    _cRepository = cRepository;

     MethodB();
  }

  public IList<int> GetA()
  {
      return _aRepository.Get();
  } 

  public IList<int> GetB()
  {
      return _bRepository.Get();
  } 

  public IList<int> GetC()
  {
      return _cRepository.Get();
  } 

  private void MethodB()
  {
      _aRepository.Init();
      _bRepository.Init();
      _cRepository.Init();
  }

  public bool MethodA(customerCollection foo){...whatever...}
}

然后在單元測試中,您可以模擬您的存儲庫並利用Moq庫

Mock<IRepository> aRepositoryMock = new Mock<IRepository>();
Mock<IRepository> bRepositoryMock = new Mock<IRepository>();
Mock<IRepository> cRepositoryMock = new Mock<IRepository>();

aRepositoryMock.Setup(m => m.Init)...setup Callback for example
aRepositoryMock.Setup(m => m.Get()).Returns(...some list...)

...aslo you can setup b and c repositories...

var sut = new A(aRepositoryMock.Object, bRepositoryMock.Object, cRepositoryMock.Object);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM