测试 protected 方法

通常单元测试是只测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);
        }
    }
}

调用私有方法

  1. 我们可能通过反射来调用私有方法
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");
        }
    }
}

  1. 使用 ExposedObject 包
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的方法一样用就行了。

最近更新的
...