模拟框架:Moq
测试框架:NUnit
我觉得有一个简单的答案,我只是忽略它,但我不能为我的生活弄清楚为什么这会给我带来悲伤。
我在这里有两个嘲讽,我正在尝试验证被测单元是否将一个mock的属性设置为另一个mock的属性,如下:
[TestFixture]
public class Testmock
{
protected Mock<IOne> mockOne;
protected Mock<ITwo> mockTwo;
protected Controller UnitUnderTest;
[SetUp]
public void Setup()
{
mockOne = new Mock<IOne>();
mockTwo = new Mock<ITwo>();
UnitUnderTest = new Controller(mockOne.Object, mockTwo.Object);
}
[Test]
public void Test1()
{
string testString = "test";
mockOne.SetupGet(o => o.Val).Returns(testString);
UnitUnderTest.CopyVal();
mockTwo.VerifySet(t => t.Val = mockOne.Object.Val);
}
}
public interface IOne
{
string Val { get; set; }
}
public interface ITwo
{
string Val { get; set; }
}
public class Controller
{
IOne one;
ITwo two;
public Controller(IOne one, ITwo two)
{
this.one = one;
this.two = two;
}
public void CopyVal()
{
two.Val = one.Val;
}
}
当我运行此测试时,它会在VerifySet
处返回错误,上面写着:
模拟上的预期调用至少一次,但从未执行过:t =&gt; t.Val =(String)null
但在那之下,说:
执行调用:ITwo.Val =“test”
所以我确定ITwo.Val
已在我的IOne.Val
中设置了Controller
,但我必须在这里为VerifySet设置模拟错误。我可以直接用字符串替换VerifySet,例如:
mockTwo.VerifySet(t => t.Val = testString);
并且测试将通过。由于mockOne.Object.Val
SetupGet
返回testString
,我不太明白为什么我不能在{{1}中使用mockOne.Object.Val
代替testString
}}
答案 0 :(得分:1)
我不确定为什么mockOne.Object.Val在VerifySet的上下文中返回null。我认为它与Moq内部实现有关(挖掘Moq源可以揭示出这种行为的原因)。
但是我可以告诉您如何在不使用 VerifySet() <中 testString 变量的情况下更改测试以使其正常工作/ strong>即可。您应该使用 It.Is(x =&gt; x == mockOne.Object.Val) ,而不是直接引用mock属性。请参阅以下内容:
[Test]
public void Test1()
{
string testString = "test";
mockOne.SetupGet(o => o.Val).Returns(testString);
UnitUnderTest.CopyVal();
mockTwo.VerifySet(t => t.Val = It.Is<string>(x => x == mockOne.Object.Val));
}
希望这有帮助。