在我的测试项目中,我想捕获SUT为模拟对象设置的属性。我尝试了很多事情,但似乎没有一个能让我捕捉到。
我举了一个简短的例子:
模拟界面:
public interface ISomeInterface
{
string SomeProperty { get; set; }
}
SUT:
public class SomeSystemUnderTest
{
public void AssignSomeValueToThis(ISomeInterface obj)
{
obj.SomeProperty = Guid.NewGuid().ToString();
}
}
测试:
[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;
}
}
“ myVal”变量保持为空,通过检查模拟,我们可以看到该属性仍然为空。只是尝试,我真的没想到它会有任何价值。
我尝试使用安装程序进行回调,但出现编译错误。
在现实生活中的项目中,SUT是将模拟的对象属性转换为依赖于另一个对象属性的对象。要知道对象是否正在执行其工作,我需要能够读取该属性。请注意,我无法重新设计模拟接口,它们是第三方。
我尝试使用VerifySet,但它似乎只采用了硬编码的值。
谢谢你, 米歇尔
答案 0 :(得分:1)
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);
另一种可能性是使用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);