Testing private methods

Hey there, I have the following code:
c#
public class Input
{
public string SelectLevel() {
string level;
bool isValid = false;

do
{
Console.WriteLine("Selecteer een level");
level = Console.ReadLine();

if (IsInputValid(level))
{
isValid = true;
}
}
while (!isValid);

return level;
}

private static bool IsInputValid(string level)
{
return !string.IsNullOrWhiteSpace(level) && level.Length > 5 && level.Contains('.');
}

public void AskInput()
{

}
}
}
c#
public class Input
{
public string SelectLevel() {
string level;
bool isValid = false;

do
{
Console.WriteLine("Selecteer een level");
level = Console.ReadLine();

if (IsInputValid(level))
{
isValid = true;
}
}
while (!isValid);

return level;
}

private static bool IsInputValid(string level)
{
return !string.IsNullOrWhiteSpace(level) && level.Length > 5 && level.Contains('.');
}

public void AskInput()
{

}
}
}
I want to unit test this code using NUnit, When creating a Setup and initializing the class these 2 methods are in, and trying to write a test for the IsInputValid I see that I cant test private methods. However, it feels needed to test that method. I worked around the issue doing the following, but this feel very ugly.
c#
[Test]
public void IsInputValid_ReturnsTrue()
{
// Arrange
MethodInfo isInputValidMethod = typeof(Input)
.GetMethod("IsInputValid",
BindingFlags.NonPublic | BindingFlags.Static);

string level = "level1.txt";
// Act
bool result = (bool)isInputValidMethod.Invoke(null, new object[] { level });

// Assert
Assert.That(result, Is.True);
}
c#
[Test]
public void IsInputValid_ReturnsTrue()
{
// Arrange
MethodInfo isInputValidMethod = typeof(Input)
.GetMethod("IsInputValid",
BindingFlags.NonPublic | BindingFlags.Static);

string level = "level1.txt";
// Act
bool result = (bool)isInputValidMethod.Invoke(null, new object[] { level });

// Assert
Assert.That(result, Is.True);
}
If you have a solution for this or adivce, I am curious to know!
4 Replies
Pobiega
Pobiega•2y ago
You can't directly test private methods, sadly. A fairly common workaround is to make it internal and use "InternalVisibleTo" to expose it to the test project. Alternatively, if you want to keep it private, use the reflection hack as above maybe write a helper for it 🙂
Tinefol
Tinefol•2y ago
You test private methods via public api, period. It can 100% be covered by public api calls (with a set of [TestCase]s). Not worth using reflection. Alternatively, extract it to a helper method as Pobiega said.
electronic heartbreak.
electronic heartbreak.OP•2y ago
Thanks both! I did read on the microsoft docs that it indeed was inappropiate to test private functions. But the positive is, is that private methods are often called by the publics, so i called the public one and tested it through there. 🙂
Pobiega
Pobiega•2y ago
yeah, thats how you do it.
Want results from more Discord servers?
Add your server