Nsubstitute,改变被替换的财产的价值

时间:2015-06-19 08:22:33

标签: c# unit-testing mocking xunit nsubstitute

我想将模型中的属性模拟为特定值(因为它有一个私有的setter)。 然后我会调用一个方法来更改此属性,然后检查结果。问题是该属性将始终返回此值。我可以以某种方式解决这个问题吗?

以下是示例:

public class Tests
{
    [Fact]
    public void Test1()
    {
        //Arrange
        var document = Substitute.For<Document>();
        document.State.Returns(DocumentState.Confirmed);

        //Act
        document.Close();

        //Assert
        Assert.Equal(DocumentState.Closed, document.State); // FAIL, State still equals "DocumentState.Confirmed"
    }
}

public class Document
{
    public virtual DocumentState State { get; private set; }

    public void Close()
    {
        if (State != DocumentState.Confirmed)
            throw new InvalidOperationException();

        State = DocumentState.Closed;
    }
}

public enum DocumentState
{
    Draft,
    Confirmed,
    Closed
}

1 个答案:

答案 0 :(得分:2)

它可能导致各种奇怪的问题,更不用说紧密耦合的测试了。如果您确实想要测试这种情况,那么您可以手动滚动可测试的存根:

public class TestableDocument : Document {
    DocumentState _state;
    bool first = true;
    public TestableDocument(DocumentState state) {
        _state = state;
    }
    public override DocumentState State {
        get {
            if (first) {
                first = false;
                return _state;
            }
            return base.State;
        }
    }
}

然后,您在测试中实例化该实例,而不是文档。

[Fact]
public void Test1()
{
    //Arrange
    var document = new TestableDocument(DocumentState.Confirmed));

    //Act
    document.Close();

    //Assert
    Assert.Equal(DocumentState.Closed, document.State); 
}

可能有办法与NSubstitute做类似的事情,但我不知道它是什么。

一般来说,如果您正在嘲笑您正在测试的课程,那么您很可能会测试错误的内容,或者您​​应该考虑重构您的代码。