通常单元测试是只测public的方法。但是有时候,我们可能会需要测试protected或者私有方法。 正常来说我们是需要把这种情况移到新的接口当中去的,然后把它变成public。
但是有时候,这些方法跟我们的其它方法是高度相关的为了高内聚,这个时候移出去,不太合适。
如下,我们要测试SettingService.Protected1,但是我们没有办法在测试类里面直接访问这个方法。 我们可以通过创建SettingServiceTestable类来达到这个效果。
public class SettingService
{
protected string Protected1(string name)
{
return $"Protected1:{name}";
}
}
public class SettingServiceTest
{
[Fact]
public void Test_Protected()
{
var settingService = new SettingServiceTestable();
settingService.Protected1("aa");
}
public class SettingServiceTestable : SettingService
{
public new string Protected1(string name)
{
return base.Protected1(name);
}
}
}
public class SettingService
{
private string Private1(string name)
{
return $"Private1:{name}";
}
}
using FluentAssertions;
using System.Reflection;
using Xunit;
namespace MyFirstUnitTests
{
public class SettingServiceTest
{
[Fact]
public void Test_Private()
{
var settingService = new SettingService();
var methodInfo = settingService.GetType().GetMethod("Private1", BindingFlags.Instance | BindingFlags.NonPublic);
var result = methodInfo.Invoke(settingService, new object[] { "name2" }) as string;
result.Should().Be("Private1:name2");
}
}
}
public class SettingService
{
private string Private1(string name)
{
return $"Private1:{name}";
}
}
using ExposedObject;
using FluentAssertions;
using Xunit;
namespace MyFirstUnitTests
{
public class SettingServiceTest
{
[Fact]
public void Test_Private()
{
var settingService = Exposed.From(new SettingService());
var result = settingService.Private1("name2") as string;
result.Should().Be("Private1:name2");
}
}
}
ExposedObject 当然也是支持Protected方法的。跟private的方法一样用就行了。