MOQ Mock void method that changes a field value

最后都变了- 提交于 2020-01-04 09:05:15

问题


I am new to MOQ and Mocking.
Assume I have a class like this, with a void method that changes a value:

public class Sample
{
    public virtual int Number { get; set; }

    public virtual void Check(int a)
    {
        this.Number = a > 10 ? this.Number = 100 : this.Number = 200;
    }
}

I want to test the void method to make sure it is changing the local field Number.

[Fact]
public void TestSampleClass()
{
    var sut = new Mock<Sample>();
    sut.Setup(s => s.Number).Returns(50);           

    sut.Setup(s => s.Check(It.IsAny<int>())).Callback(
        (int testNumber) =>
        {
            if (testNumber > 10)
            {
                sut.Setup(s => s.Number).Returns(100);
            }
            else
            {
                sut.Setup(s => s.Number).Returns(200);
            }                   
        });
}

It seems that the method doesn't change the value to 100 or 200... If I print sut.Object.Number it gives the initial value, not the updated one after void call.


回答1:


Unless your example is a simplified representation of a much more complicated problem, there is no need to mock the Sample class.

[Fact]
public void TestSampleClass()
{
    //Arrange
    var testNumber = 5; //Could be what ever number you want to test
    var expected = 200
    var sut = new Sample();

    //Act
    sut.Check(testNumber);
    var actual = sut.Number;

    //Assert
    Assert.AreEqual(expected, actual);
}

If the intention was to learn how to perform such a test in this particular situation then you can do something like this...

Assuming you wanted to test that the Check method on the following interface...

public interface ISample {
    int Number { get; set; }
    void Check(int a);
}

where the expected behavior is to have the method change the value of a property using Moq then this is how you can set it up.

[Fact]
public void TestISampleCheck() {
    //Arrange
    var testNumber = 5; //Could be what ever number you want to test
    var expected = 200;
    var mock = new Mock<ISample>();

    //Specifies that the all properties on the mock should have "property behavior",
    //meaning that setting its value will cause it to be saved and later returned
    //when the property is requested. (this is also known as "stubbing"). The default
    //value for each property will be the one generated as specified by the Moq.Mock.DefaultValue
    //property for the mock.
    mock.SetupAllProperties();

    var sut = mock.Object;

    mock.Setup(s => s.Check(It.IsAny<int>()))
        .Callback((int a) => {
            if (a > 10) {
                sut.Number = 100;
            } else {
                sut.Number = 200;
            }
        });

    //Act
    sut.Check(testNumber);
    var actual = sut.Number;

    //Assert
    Assert.AreEqual(expected, actual);
}



回答2:


Callback method just sets the behavior of the method, to make some changes you actually need to call mocked method i.e. sut.Object.Check(11);, then you can assert your results.



来源:https://stackoverflow.com/questions/36761339/moq-mock-void-method-that-changes-a-field-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!