I hate to be bringing this up again, but I'm really trying to understand how to safeguard something with my tests.
I have a public method (below) that calls a private method before calling another method that actually takes some action. I want to make sure that the call to the private method doesn't get removed because that could be catastrophic. I've done some research, here, here, and here, and they all say not to test private methods. I can understand that, I guess, but then how do I safeguard against the removal of this line of code?
As you can see, the public method returns void, so I can't test the results of the public method call. And I have unit tests that test ApplicationShouldBeInstalled()
directly.
public void InstallApplications()
{
foreach (App app in this._apps)
{
// This is the line of code that can't be removed. How can I make
// sure it doesn't get removed?
if (!ApplicationShouldBeInstalled(app)) { continue; }
// This simply can't run unless it passes the above call.
CommonUtility.Container.Resolve<IAppInstaller>().InstallApplication(this, app);
}
}
EDIT - I went with this, based on JerKimball's answer.
Basically, I just use a Mock object (from Moq), and then verify that its method was called the expected number of times.
[TestMethod()]
public void ApplicationShouldBeInstalledTest_UseCase13()
{
var mockAppInstaller = new Mock<IAppInstaller>();
mockAppInstaller.Setup(m => m.InstallApplication(It.IsAny<ApplicationServer>(),
It.IsAny<Application>()));
CommonUtility.Container.RegisterInstance<IAppInstaller>(mockAppInstaller.Object);
// Actual test code here
appServer.InstallApplications();
mockAppInstaller.Verify(x => x.InstallApplication(It.IsAny<ApplicationServer>(),
It.IsAny<Application>()), Times.Never());
}
I can't let this go; that edit is just ugly. Even though I have to create an actual mock class, this approach is much cleaner:
Mock implementation:
public class MockAppInstaller : IAppInstaller
{
public bool Invoked { get; set; }
public void InstallApplication(ApplicationServer server, Application app)
{
this.Invoked = true;
}
}
Test method:
[TestMethod()]
public void ApplicationShouldBeInstalledTest_UseCase14()
{
MockAppInstaller mockAppInstaller = new MockAppInstaller();
CommonUtility.Container.RegisterInstance<IAppInstaller>(mockAppInstaller);
// Actual test code here
appServer.InstallApplications();
Assert.AreEqual(true, mockAppInstaller.Invoked);
}