从基础 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);
我目前正在开发 .NET 5.0 应用程序。
我需要对实现受保护 属性 protected IMediator Mediator
.
我的 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);