问题
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