0

模拟框架:起订量
测试框架:NUnit

我觉得对此有一个简单的答案,而我只是忽略了它,但我一生都无法弄清楚为什么这让我感到悲伤。

我在这里有两个模拟,我正在尝试验证被测单元是否将一个模拟的属性设置为另一个模拟的属性,如下所示:

[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 => t.Val = (String)null

但在这之下,说:

执行的调用:ITwo.Val = "test"

所以我肯定知道在我的 中ITwo.Val设置了,但我必须在这里为 VerifySet 设置错误的模拟。我可以直接用字符串替换 VerifySet,例如:IOne.ValController

mockTwo.VerifySet(t => t.Val = testString);

并且测试将通过。既然mockOne.Object.ValSetupGetreturn testString,我不太明白为什么不能用mockOne.Object.Valin placetestString代替VerifySet

4

1 回答 1

1

我不确定为什么 mockOne.Object.Val 在 VerifySet 的上下文中返回 null。我相信这与 Moq 内部实现有关(挖掘 Moq 来源可以揭示这种行为的原因)。

但是,我可以告诉您如何更改您的测试以使其工作,而无需在VerifySet()中使用testString变量。您应该使用It.Is(x => x == mockOne.Object.Val)而不是直接引用模拟属性。请看下面:

[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));
}

希望这可以帮助。

于 2013-10-22T17:33:06.503 回答