使用另一个模拟验证集返回null

时间:2013-10-22 16:10:10

标签: c# nunit moq

模拟框架: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 }}

1 个答案:

答案 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));
}

希望这有帮助。