![](/img/trans.png)
[英]How to create mock for method that is called using object instance in MOQ 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容器包括Ninject , StructureMap , Castle 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.