.Net core library: How to test private methods using xUnit
For testing internal classes, @Patric's answer is correct.
Private methods are private for a good reason, supposedly. They should not become internal, again for a good reason.
(And some ppl argue that we should not write unit tests for private methods. Why? Well, because they are "private"! But if you are so serious to write unit tests for private methods:)
This is a much better way to test private methods:
public class Hello
{
private string _firstName { get; set; }
private string _lastName { get; set; }
public Hello(string firstName, string lastName)
{
_firstName = firstName;
_lastName = lastName;
}
public string HelloMan()
{
if (string.IsNullOrEmpty(_firstName))
throw new Exception("Missing First Name.");
return this.HelloMan(_firstName, _lastName);
}
private string HelloMan(string firstName, string lastName)
{
return $"Hello {firstName} {lastName}!";
}
}
The test goes like:
public class HelloTests
{
[Fact]
public void PrivateHelloManShouldBeWellFormated()
{
// Arrange
var firstName = "John";
var lastName = "Doe";
Type type = typeof(Hello);
var hello = Activator.CreateInstance(type, firstName, lastName);
MethodInfo method = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
.Where(x => x.Name == "HelloMan" && x.IsPrivate)
.First();
//Act
var helloMan = (string)method.Invoke(hello, new object [] {firstName, lastName});
//Assert
helloMan
.Should()
.StartWith("Hello")
.And
.EndWith("!")
.And
.Contain("John")
.And
.Contain("Doe");
}
}
Reference:
http://anthonygiretti.com/2018/08/26/how-to-unit-test-private-methods-in-net-core-applications-even-if-its-bad/
A quick solution is to make private
members that you want to test internal
.
You can then add an InternalsVisibleTo
attribute to your main library's AssemblyInfo.cs. This will allow your test library (and no other library, without reflection) access to the internal methods/classes in your main library.
e.g.
[assembly: InternalsVisibleTo("Library.Tests")]