如何模拟受保护的字段?

时间:2010-11-22 21:10:15

标签: c# unit-testing mocking bdd xunit.net

我正在尝试在类NodeIdGenerator中模拟受保护的字段。我想在构造函数中设置字段的值,然后调用属于GetNext()的{​​{1}}方法。

我很确定我的测试没问题:

NodeIdGenerator

我的问题出在模拟课上。当我在测试中调用public class NodeIdGeneratorTests { [Fact(DisplayName = "Throws OverflowException when Int32.MaxValue " + "IDs is exceeded")] public void ThrowsOverflowExceptionWhenInt32MaxValueIdsIsExceeded() { var idGenerator = new NodeIdGeneratorMock(Int32.MaxValue); Assert.Throws(typeof(OverflowException), () => { idGenerator.GetNext(); }); } /// <summary> /// Mocks NodeIdGenerator to allow different starting values of /// PreviousId. /// </summary> private class NodeIdGeneratorMock : NodeIdGenerator { private new int? _previousId; public NodeIdGeneratorMock(int previousIds) { _previousId = previousIds; } } } 时,它使用属于超类的GetNext()对象,而不是我想要它使用的对象(在模拟类中)。

那么,如何模拟受保护的字段?

PS:我读过this question,但我似乎无法做出头脑或尾巴!

2 个答案:

答案 0 :(得分:1)

如果可能的话,最好让previousId成为虚拟财产并覆盖模拟中的getter:

public class NodeIdGenerator
{
    protected virtual int? PreviousId { ... }
}

private class NodeIdGeneratorMock : NodeIdGenerator
{
    protected override int? PreviousId
    {
        get { return _previousId; }
    }
}

答案 1 :(得分:1)

您发布的代码将_previousId声明为new,因此它会隐藏基类'字段 - 它不会覆盖它。当您调用GetNext时,基类将不会使用该值,它将使用自己的字段。

尝试删除您的声明,只需访问基类'protected field。