nsubstitute属性getter override不起作用

时间:2014-07-01 13:08:35

标签: c# nsubstitute

我是nsubstitute测试的新手。所以这对你来说可能是一个微不足道的问题。但我找不到一个。我请你帮我解决以下问题。

我通过测试抽象类来解决问题:

public abstract class BaseClass
{
    public string Name
    {
        get { return GetName(); }
        set { SetName(value); }
    }

    protected abstract string GetName();

    protected abstract void SetName(string value);

}

我想测试一下,如果在抽象类中正确调用了getter和setter。为了获取受保护的抽象方法,我派生了类:

public class MockClass:BaseClass
{
    protected override string GetName()
    {
        return MockGetName();
    }

    protected override void SetName(string value)
    {
        MockSetName(value);
    }

    public virtual string MockGetName()
    {
        return string.Empty;
    }

    public virtual void MockSetName(string value)
    {
    }
}

现在我想测试一下,如果调用了MockGetName() - Method,那么在获取Name-Property的值时:

public void TestNameGetter()
{
    // arrange
    MockClass mock = Substitute.For<MockClass>();
    mock.MockGetName().Returns(" Irgendein Name ");

    // act
    string name = mock.Name;

    // assert
    Assert.AreEqual(" Irgendein Name ", name, "Wrong name");
    mock.DidNotReceive().MockSetName(Arg.Any<string>());
    mock.Received().MockGetName();
}

但是从不调用方法MockGetName,并且变量名具有错误的值。

我希望任何人都可以帮我测试功能。感谢

1 个答案:

答案 0 :(得分:2)

问题是NSubstitute正在拦截MockClass.GetName调用并返回默认值(空字符串)。因此,当mock.Name在测试中运行时,它会调用GetName并返回空字符串,无论MockGetName将返回什么。

我不确定您到底想要实现的目标,但如果您想使用NSubstitute进行此类操作,首先想到的选项是直接使用该属性,或者更改GetName公开。或者,避免使用NSubstitute并将测试所需的逻辑直接放入MockClass

Mockable属性

    public abstract class BaseClass
    {
        public virtual string Name { get; set; }
    }

    [Test]
    public void TestNameGetter()
    {
        var mock = Substitute.For<BaseClass>();
        mock.Name.Returns("ABC");

        string name = mock.Name;

        Assert.AreEqual("ABC", name, "Wrong name");
    }

公共访问者方法

    public abstract class BaseClass
    {
        public string Name
        {
            get { return GetName(); }
            set { SetName(value); }
        }

        public abstract string GetName();
        public abstract void SetName(string value);
    }

    [Test]
    public void TestNameGetter()
    {
        var mock = Substitute.For<BaseClass>();
        mock.GetName().Returns("ABC");

        string name = mock.Name;

        Assert.AreEqual("ABC", name, "Wrong name");
        mock.DidNotReceive().SetName(Arg.Any<string>());
        mock.Received().GetName();
    }

手写模拟

    public class MockClass : BaseClass
    {
        public bool GetNameWasCalled = false;
        public bool SetNameWasCalled = false;
        protected override string GetName() { GetNameWasCalled = true; return "ABC"; }
        protected override void SetName(string value) { SetNameWasCalled = true; }
    }

    [Test]
    public void TestNameGetter()
    {
        // arrange
        var mock = new MockClass();

        // act
        string name = mock.Name;

        // assert
        Assert.AreEqual("ABC", name, "Wrong name");
        Assert.False(mock.SetNameWasCalled);
        Assert.True(mock.GetNameWasCalled);
    }