我有一个控制台应用程序,用户输入一个数字,我根据该数字生成一个功能。我使用了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
用户输入为&#34; 7&#34; ,
当我创建FeatureService
时,我将{strong> 3 放在howManyFeatures
- 测试失败(没有具体实施)。
现在,当我正常运行我的程序时 - 如果我输入&#34; 7&#34;,程序按预期运行并输出错误信息。
当我运行测试时,除了HowManyFeatures + 1
之外,每个对consoleMock的输入都通过了测试(HowManyFeatures +1
失败,因为它没有进入while
),它不应该是这样的 - 对于没有具体IFeature
实现的数字(仅有1,2和3具有具体实现),它应该失败。
我该如何解决这个问题?我应该带#34;进入Ninject Bindings
项目的Tests
?我应该测试这种方法吗?还是一切都没用?
感谢任何想法
答案 0 :(得分:1)
您不需要将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实现中使用它,它将使您的测试更容易。