如何使用 Mock (Moq) 捕获属性值的设置

use*_*647 5 c# moq mocking

在我的测试项目中,我想捕获 SUT 设置为模拟对象的属性。我尝试了很多事情,但似乎没有一个能让我捕捉到这一点。

我设置了一个简短的例子:

模拟的界面:

public interface ISomeInterface
{
    string SomeProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

被测系统:

public class SomeSystemUnderTest
{
    public void AssignSomeValueToThis(ISomeInterface obj)
    {
        obj.SomeProperty = Guid.NewGuid().ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

考试:

[TestClass]
public class SomeTests
{
    [TestMethod]
    public void TestSomeSystem()
    {
        // Arrange
        var someInterfaceMock = new Mock<ISomeInterface>();

        someInterfaceMock.SetupSet(m => m.SomeProperty = It.IsAny<string>()).Verifiable();

        // Act
        var sut = new SomeSystemUnderTest();
        sut.AssignSomeValueToThis(someInterfaceMock.Object);

        // Assert
        // HERE I WOULD LIKE TO READ WHAT VALUE WAS ASSIGNED
        string myVal = someInterfaceMock.Object.SomeProperty;
    }
}
Run Code Online (Sandbox Code Playgroud)

“myVal”变量保持为空,通过检查模拟,我们可以看到该属性仍然为空。我并没有真正期望它有任何价值,只是尝试一下。

我尝试使用安装程序,通过回调,出现编译错误。

在现实项目中,SUT 是将模拟对象属性转换为依赖于另一个对象属性的东西。要知道该对象是否正在执行其工作,我需要能够读取该属性。请注意,我无法重新设计模拟接口,它们是第三方的。

我尝试使用VerifySet,但它似乎只采用硬编码值。

谢谢你,米歇尔

Joh*_*nny 10

get和之间存在差异,set并且模拟实际上没有任何内部状态,而只有它尝试匹配和正常运行的设置。您可以通过使用回调来模拟真实get的功能。set像这样的东西:

//Arrange
string someProperty = null;
var mock = new Mock<ISomeInterface>();

mock.SetupSet(m => m.SomeProperty = It.IsAny<string>())
    .Callback<string>(p => someProperty = p)
    .Verifiable();

// use func instead of value to defer the resulution to the invocation moment
mock.SetupGet(m => m.SomeProperty).Returns(() => someProperty);

//Act
mock.Object.SomeProperty = "test";

//Assert
Assert.AreEqual("test", mock.Object.SomeProperty);
Run Code Online (Sandbox Code Playgroud)

另一种可能性是使用Capture 它本身,它实际上存在于moq

//Arrange
List<string> someProperty = new List<string>();
var mock = new Mock<ISomeInterface>();

mock.SetupSet(m => m.SomeProperty = Capture.In(someProperty))
    .Verifiable();

mock.SetupGet(m => m.SomeProperty).Returns(() => someProperty.Last());

//Act
mock.Object.SomeProperty = "test";

//Assert
Assert.AreEqual("test", mock.Object.SomeProperty);
Run Code Online (Sandbox Code Playgroud)