从基础 class 单元测试受保护属性的正确方法

Correct way to unit test protected properties from base class

我目前正在开发 .NET 5.0 应用程序。

我需要对实现受保护 属性 protected IMediator Mediator.

的抽象基础 class 进行单元测试

我的 class 看起来像这样:

public abstract class MyControllerBase : Controller
{
    protected IMediator Mediator { get; }

    protected MyControllerBase(IMediator mediator)
    {
       Mediator = mediator;
    }
}

我的单元测试是这样的:

[Fact]
[Trait(nameof(TestTraitName.Category), nameof(TestType.Unit))]
public void MyControllerTests()
{
    var testController = new TestController(new Mediator(Mock.Of<ServiceFactory>()));

    Assert.NotNull(anotherAuthController.TestMediator);
 }
}

 public class TestController : MyControllerBase
{
   public IMediator TestMediator { get; set; }

   public AnotherController(IMediator mediator)
   : base(mediator)
   {
      TestMediator = mediator;
   }
}

当我 运行 我的单元测试时,不幸的是受保护的 属性 没有被我的测试覆盖。

你知道吗,在 C# 中从抽象基础 class 单元测试受保护的 属性 的正确方法是什么?

你知道如何解决这个问题吗?

在这种情况下,我建议让 public 属性 暴露基础 属性

public class TestController : MyControllerBase {
    public IMediator TestMediator => base.Mediator;

    public TestController(IMediator mediator) : base(mediator) {
      
    }
}

[Fact]
[Trait(nameof(TestTraitName.Category), nameof(TestType.Unit))]
public void MyControllerTests() {
    var testController = new TestController(Mock.Of<IMediator>());    
    Assert.NotNull(testController.TestMediator);
}

试试这个。对我来说,这与 NSubtitute 一起用于受保护的属性。

public abstract class MyControllerBase : Controller
{
    protected virtual IMediator Mediator { get; }

    protected MyControllerBase(IMediator mediator)
    {
       Mediator = mediator;
    }
}

public class MyControllerBaseWrapper : MyControllerBase {
    protected override IMediator Mediator => base.Mediator;

    public MyControllerBaseWrapper(IMediator mediator) : base(mediator)
    {
      
    }
    
    public IMediator GetMediator()
    {
       return Mediator;
    }

}

[Fact]
[Trait(nameof(TestTraitName.Category), nameof(TestType.Unit))]
public void MyControllerTests() {
    var expectedValue = Substitute.For<IMediator>();
    var testController = Substitute.For<MyControllerBaseWrapper>(expectedValue);
    testController.GetType().GetProperty("Mediator", BindingFlags.NonPublic | BindingFlags.Instance)
            .GetValue(testController, null).Returns(expectedValue);

    Assert.EreEqual(expectedValue,testController.GetMediator());
}

这里我对子保护属性使用了反射。

testController.GetType().GetProperty("Mediator", BindingFlags.NonPublic | BindingFlags.Instance)
                .GetValue(testController, null).Returns(expectedValue);