Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MOQ Mock void method that changes a field value

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.

like image 842
Behrang d12 Avatar asked Sep 21 '25 00:09

Behrang d12


1 Answers

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);
}
like image 113
Nkosi Avatar answered Sep 22 '25 13:09

Nkosi