2016-08-24 44 views
0

試圖教我自己SimpleInjector和我掌握的基本知識,但需要一些幫助。通過簡單注射器傳遞類變量

本質上我想通過簡單的注入器來傳遞一個對象,而我已經填充了這個對象而不是一個新的對象。

示例情況我是如下:

ITeaService:

public interface ICup 
{ 
    string CupName { get; set; } 
    List<string> Ingredients { get; set; } 
} 
public class Cup : ICup 
{ 
    public string CupName { get; set; } 
    public List<string> Ingredients { get; set; } 

} 
public interface ITeaService 
{ 
    ICup GetTea(); 
} 

TeaService:

public class TeaService : ITeaService 
{ 
    private ICup _cup; 

    public TeaService(ICup cup) 
    { 
     _cup = cup; 
    } 

    public ICup GetTea() 
    { 

     this._cup.Ingredients.Add("Tea bag"); 
     this._cup.Ingredients.Add("Hot water"); 

     return this._cup; 
    } 
} 

測試:

var container = new SimpleInjector.Container(); 
     container.Register<ITeaService, TeaService>(); 
     container.Register<ICup, Cup>(); 

     container.Verify(); 
     // Act 
     var cp = container.GetInstance<ICup>(); 
     cp.CupName = "Daniel"; 


     var teaService = container.GetInstance<ITeaService>(); 
     var cup = teaService.GetTea(); 

任何想法我如何傳遞預先定義的C.通過?是我指定了CupName的變量cp?

+1

也許你的例子只是爲了學習的目的,但在實踐中這個例子沒有任何意義,甚至可能使事情複雜化並使你困惑。 'Cup'似乎是一個實體,實體不是由DI容器管理的。 DI容器管理服務和服務通常是不可變的。 '杯'然而是一個可變的實體。 – Steven

回答

3

以下行不正確:

container.Register<ICup, Cup>(); 

這裏你告訴SimpleInjector每當請求的ICup創建一個新的Cup。它更改爲以下總是返回相同的Cup

var standardCup = new Cup(); 
standardCup .CupName = "Daniel"; 
container.RegisterSingleton<ICup>(standardCup); 

現在,這個測試會成功:

var teaService = container.GetInstance<ITeaService>(); 
var cup = teaService.GetTea(); 
Assert.AreEqual(cup.CupName, "Daniel"); 
Assert.AreEqual(cup, standardCup); 

編輯:基於評論:如果你總是希望有一個新的實例,但具有相同名稱,你可以做到以下幾點:

container.Register<ICup>(() => new Cup { CupName = "Daniel"}); 

這將運行回調每次構建Cup您請求ICup

+0

我不想每次都使用同樣的杯子,基本上我想要一個新的杯子,但我希望能夠以某種方式傳遞名稱 – Webezine

+0

爲什麼你想通過DI來做到這一點?當你拿到新的杯子時,你可以在之後設置名字。 – Kenneth

+0

當我在測試中進行驗證時,它說cupname爲空,不能這樣,所以我想在創建新的事件時找到一種方法來通過cupname。 – Webezine

0

您的第一個問題是您實際測試的是什麼?

您編寫測試的方式是測試SimpleInjector的工作方式,而不是您的代碼工作。

您需要使用實現該接口的類的測試,因爲您需要真正的代碼來測試任何內容。

我會做的是這樣的:

  1. 創建一個實現了一個ICUP杯類 - 你可能已經擁有了它。
  2. 創建它的一個實例並將其傳遞給您的服務類的構造函數。
  3. 測試您期望的輸出是否爲corect。

你真的希望你的測試是有價值的,並且遠離DI和IOC測試真正的功能,無論如何都能保證正常工作。

有意義嗎?你正在測試Cup類,更可能是服務類,真正的類而不是抽象類,它們根據定義沒有功能,因此沒有任何可測試的東西。

想象一下當你有兩個實現ICup的類時會發生什麼。你會寫兩個測試類,每個實現一個。

更多細節加入基於評論

您的測試方式更簡單呢。

所有你需要做的就是測試一旦你添加一個成分,它實際上出現在Cup對象的成分列表中。這意味着你只需要測試杯類,該服務在這個時候對你沒有任何幫助。測試一下你能做到的最簡單的互動,一旦你做了這些工作,你就可以一步步地走向更復雜的事情。

因此,編寫CupTests類。測試當你添加一種成分時,它實際上出現在成分列表中,檢查錯誤和邊界錯誤,例如當你嘗試添加某些成分時,成分列表爲空時會發生什麼。

這就是你所需要的基於你迄今爲止顯示的內容。

+0

90%的這一切都超過了我的腦海。我沒有包括這些測試,但他們測試了杯子裏有添加成分,並且他們是我在測試服務中添加的成分。需要rayman類型isntructions在這裏... – Webezine

+0

我已經完成了這一步,併成功 - 但是 - 將杯子名添加到杯類後我試圖找到一種方法來通過杯名... – Webezine

+0

儘管我同意你的意見,並沒有真正回答這個問題。這更多的是對測試原因和方式的評論。我假設測試只是爲了舉例說明他所看到的行爲。 – Kenneth