[英]c# - unit testing, mock and ninject factory extension
我有一個控制台應用程序,用戶可以在其中輸入一個數字,然后根據該數字生成一個功能。 我Ninject.Extensions.Factory
使用了Ninject.Extensions.Factory
,這里是綁定:
Bind<IFeature>().To<FirstFeature>().Named("1");
Bind<IFeature>().To<SecondFeature>().Named("2");
Bind<IFeature>().To<ThirdFeature>().Named("3");
Bind<IFeatureFactory>().ToFactory(() => new UseFirstArgumentAsNameInstanceProvider());
我要測試的代碼是:
構造函數:
public FeatureService(IFeatureFactory featureFactory, IUILayer uiHandler, int howManyFeatures)
{
this.featureFactory = featureFactory;
this.uiHandler = uiHandler;
this.howManyFeatures = howManyFeatures;
}
被測方法:
public async Task startService()
{
bool isBadInput = false;
string userSelection = null;
uiHandler.displayMenu(howManyFeatures);
userSelection = uiHandler.getSelection();
while (!userSelection.Equals((howManyFeatures+1).ToString()))
{
IFeature feature = null;
try
{
feature = featureFactory.createFeature(userSelection);
isBadInput = false;
}
catch (ActivationException ex)
{
uiHandler.displayErrorMessage();
isBadInput = true;
}
if (!isBadInput)
{
await feature.execFeature();
}
uiHandler.displayMenu(howManyFeatures);
userSelection = uiHandler.getSelection();
}
}
如您所見,當我try
createFeature
,我catch
了ActivationException
,這意味着用戶輸入了無效的選擇(ninject 無法獲取具體類),並且沒有調用execFeature
。
我正在嘗試編寫一個單元測試來測試當用戶輸入有效選擇時,調用execFeature
方法。
這是測試:
[TestMethod]
public void WhenUserEnterValidSelectionExecFeatureCalled()
{
//Arrange
Mock<IFeature> featureMock = new Mock<IFeature>();
Mock<IConsoleService> consoleServiceMock = new Mock<IConsoleService>();
// mock user input 7
consoleServiceMock.Setup(c => c.ReadLine()).Returns("7");
IUILayer uiLayer = new ConsoleUILayer(consoleServiceMock.Object);
Mock<IFeatureFactory> featureFactory = new Mock<IFeatureFactory>();
featureMock.Setup(t => t.execFeature());
featureFactory.Setup(t => t.createFeature(It.IsAny<string>())).Returns(featureMock.Object);
// init FeatureService with 3 features
IFeatureService featureService = new FeatureService(featureFactory.Object, uiLayer, 3);
//Act
featureService.startService();
//Assert
featureMock.Verify(t => t.execFeature());
}
正如你所看到的-我的創建consoleMock
與“7”的用戶輸入,而當我創建FeatureService
我把3在howManyFeatures
-測試應該失敗(沒有具體的實現)。
現在,當我正常運行程序時 - 如果我輸入“7”,程序會按預期運行並輸出錯誤消息。
當我運行測試時,除了HowManyFeatures + 1
之外, HowManyFeatures + 1
每個輸入都通過了測試( HowManyFeatures +1
失敗,因為它沒有進入while
),它不應該是這樣 - 它應該失敗的數字沒有具體的IFeature
實現(只有 1、2 和 3 有具體的實現)。
我該如何解決這個問題? 我應該將Ninject Bindings
“帶入” Tests
項目嗎? 我什至應該測試這種方法嗎? 還是一切都沒用?
任何想法表示贊賞
您不需要將 ninject 綁定帶入您的測試,您的 FeatureService 不需要知道您的 IFeatureFactory 是基於 ninject 綁定,它並不關心它。
您需要做的是正確設置您的 IFeatureFacotory 模擬,現在無論輸入是什么,您的模擬都會返回相同的 IFeature,因為這是您告訴它使用的行為:
featureFactory.Setup(t => t.createFeature(It.IsAny<string>())).Returns(featureMock.Object);
如果您希望它在獲取的數字大於 3 時拋出 ActivationException,只需設置此所需的行為即可:
featureFactory.Setup(t => t.createFeature(It.Is<string>(input => (int)input>3 ))).Throws(new ActivationException());
順便說一句,您可能應該直接模擬 IUiLayer 並將其注入到 FeatureService 而不是模擬您的 consoleService 並在您真正的 UiLayer 實現中使用它,這將使您的測試更加容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.