I have a console app where the user inputs a number, and I generate a feature according to that number. I have used Ninject.Extensions.Factory for that, here are the bindings:
Bind<IFeature>().To<FirstFeature>().Named("1");
Bind<IFeature>().To<SecondFeature>().Named("2");
Bind<IFeature>().To<ThirdFeature>().Named("3");
Bind<IFeatureFactory>().ToFactory(() => new UseFirstArgumentAsNameInstanceProvider());
The code I want to test is:
constructor:
public FeatureService(IFeatureFactory featureFactory, IUILayer uiHandler, int howManyFeatures)
{
this.featureFactory = featureFactory;
this.uiHandler = uiHandler;
this.howManyFeatures = howManyFeatures;
}
method under test:
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();
}
}
As you can see, when I try to createFeature, I catch the ActivationException, meaning that the user has input invalid selection (ninject fails to get the concrete class), and execFeature is not called.
I am trying to write a unit test to test that when a user inputs a valid selection, the method execFeature is called.
Here is the test:
[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());
}
As you can see - I an creating a consoleMock with user input of "7", and when I create the FeatureServiceI put 3 in the howManyFeatures - Test should fail (no concrete implementation).
Now, when I run my program normally - if I input "7", the program acts as expected and outputs an error message.
When I run the test, every input to the consoleMock besides the HowManyFeatures + 1 passes the test (HowManyFeatures +1 fails because it doesn't go into the while), and it shouldn't be like that - it should fail for the number that don't have a concrete IFeature implementation (only 1, 2 and 3 have concrete implementations).
How do I solve this? Should I "bring" the Ninject Bindings into the Tests project? should I even test this method? or its all useless?
Any thoughts are appreciated
Aucun commentaire:
Enregistrer un commentaire