簡體   English   中英

如何在C#中的方法內部創建模擬實例?

[英]How do I create a mock instance inside of a method in C#?

因此,這是我的課程的簡化版本。 我有兩個實現服務接口的類。 一種是我的實際實現,一種是我的模擬。
我需要在Worker類中創建X個此服務類的新實例。

如何告訴我的Worker類我要使用哪個IService?
模擬工人階級是唯一的選擇嗎? 有更好的路線嗎?

編輯:因此,在閱讀了一些答復之后,我感到我沒有准確傳達我的情況。 我簡化到了阻礙的地步。 無論如何,我添加了更多代碼,可能有助於解釋我的情況。

我將原來的Worker類更改為Manager並有一個Workers子列表。 工人列表是從Manager類創建的,我使用IService構造它們,我想將其傳遞給Concrete或Mock實現。 然后,我將啟動Workers來執行涉及IService和我提供的變量的操作。 (在這種情況下,它只是一個整數,但在現實生活中,它是一個類)。

public interface IService
{
    int a { get; set; }
}

public class Concrete : IService
{
    public int a { get; set; }
    float x;

    public Concrete(int A)
    {
        a = A;
        x = 0.500F;
    }
}

public class Mock : IService
{
    public int a { get; set; }
    float x;

    public Mock(int A)
    {
        a = A;
        x = 0.750F;
    }
}

public class Manager
{
    List<Worker> Workers = new List<Worker>();

    void CreateList() 
    {
        for (int i = 1; i <= 3; i++)
        {
            Worker w = new Worker(new IService(i)); //<-- Need help here!
            theList.Add(w);
        }

        KickOffWorkesAsync();
    }

    void KickOffWorkesAsync()
    {
        // process the workers async
    }

}

public class Worker
{
    IService _iService;

    public Worker(IService _iSer)
    {
        _iService = _iSer;
    }

    void DoSomething() 
    {
        //do work with _iService
    }
}

這是依賴注入派上用場的地方。 您需要設計類以從外部獲取它們的依賴關系,而不是自己創建它們。

就像是:

public class Worker
{
  public Worker(IService service) 
  {
    this.service = service;
  }

  public void DoSomething()
  {
    DoSomethingWith(service);
  }
}

然后,在測試中,您可以創建一個注入了模擬服務的Worker實例,而在生產代碼中,您將使用真實服務。

使用依賴注入時,使用DI容器(有時也稱為控制容器反轉)有助於正確地連接依賴服務,而不是手動創建依賴圖。 .NET的一些常見DI容器包括NinjectStructureMapCastle Windsor和Microsoft的Unity

如果您以前從未使用過DI,那將是一個范式轉換,但是從本質上講,這是一個簡單的更改,可以使您的代碼設計產生奇跡(由於許多原因,而不僅僅是出於測試目的)。

另一種選擇是給worker提供一種工廠方法來創建服務:

public class Worker
{
    private Func<int, IService> createService;

    public Worker(Func<int, IService> createService)
    {
        this.createService = createService;
    }

然后,工人可以執行以下操作:

void DoSomething() 
{
    var theList = new List<IService>();
    for (int i = 1; i <= 3; i++)
    {
        IService s = createService(i); // Invoke the provided factory method
        theList.Add(s);
    }

    // do something with the list...
}

並且單元測試可以像這樣創建工作程序:

public void SomeTestMethod()
{
    var worker = new Worker(CreateMockService);
}

private IService CreateMockService(int arg)
{
    return new Mock(arg);
}

生產代碼將提供創建真實服務的工廠方法。

盡可能簡單地回答您的問題。

  void DoSomething() 
  {
      var theList = new List<IService>();
      for (int i = 1; i <= 3; i++)
      {
          //use this
          IService s = new Concrete(i); 
          //or this
          //IService s = new new Mock(i);
          theList.Add(s);
      }

      // do something with the list...
  }

但是更好的方法是使用某種類型的依賴項注入或工廠(如其他答案所述),因此您可以在配置文件中或在應用啟動時指定要使用的IService

暫無
暫無

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

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