MOQ Mock void方法,用于更改字段值

时间:2016-04-21 06:29:05

标签: c# unit-testing mocking moq

我是MOQ和Mocking的新手 假设我有一个这样的类,使用一个改变值的void方法:

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;
    }
}

我想测试void方法以确保它正在更改本地字段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);
            }                   
        });
}

似乎该方法没有将值更改为100或200 ... 如果我打印sut.Object.Number,它会给出初始值,而不是在无效调用后更新的值。

2 个答案:

答案 0 :(得分:2)

除非您的示例是更复杂问题的简化表示,否则无需模拟Sample类。

[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);
}

如果打算在这种特殊情况下学习如何进行这样的测试,那么你可以做这样的事情......

假设您想在以下界面上测试Check方法......

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

其中预期的行为是让方法使用Moq更改属性的值,然后就可以设置它了。

[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);
}

答案 1 :(得分:0)

Callback方法只是设置方法的行为,进行一些实际需要调用mocked方法的更改,即sut.Object.Check(11);,然后你可以断言你的结果。