验证是否使用Moq调用方法

时间:2014-11-24 14:56:58

标签: c# mocking moq

使用Moq框架进行UnitTesting C#代码时出现以下问题:

我无法检查执行给定方法( TestCaseExecutions.Add())的次数。执行计数器始终为零。

在“问题就在这里”评论中有两行标记为“1”和“2”。

“1”负责迭代 TestCaseExecutions.Add(TestCaseExecution)呼叫计数器。
方法 SomeMethodThatUsesMockedContext(mockContext.Object)对此表的操作需要“2”,没有它任何linq查询都会抛出空指针异常。

在评论出“2”行和 SomeMethodThatUsesMockedContext 方法并添加

之后
mockContext.Object.TestCaseExecutions.Add(new TestCaseExecution());

验证方法之前

如何解决此问题以及为什么使用“2”行以某种方式中和“1”行?

[Test()]
public void SomeTest()
{
    //Internal counters.
    int saveChanges = 0;
    int AddedExecutions = 0;

    //Mock DatabaseContext
    var mockContext = new Mock<TestRunsEntities>();
    mockContext.Setup(x => x.SaveChanges()).Callback(() => saveChanges++);
    ...

    //Mock of one of it's tables
    var mockTestCaseExecution = new Mock<DbSet<TestCaseExecution>>();

    //PROBLEM IS HERE (I think)
    mockContext.Setup(x => x.TestCaseExecutions.Add(It.IsAny<TestCaseExecution>())).Callback(() => addExecution++); //1
    mockContext.Setup(c => c.TestCaseExecutions).Returns(mockTestCaseExecution.Object); //2


    //Inside this method Save(), and TestCaseExecutions.Add(TestCaseExecution ex) are called.
    //I have checked in debug mode that they are called once for my test scenario.
    SomeMethodThatUsesMockedContext(mockContext.Object);

    //After execution, saveChanges is equal to 1 as expected but AddedExecutions is equal to 0

    //This step fails.
    mockContext.Verify(x => x.TestCaseExecutions.Add(It.IsAny<TestCaseExecution>()), Times.Once());

    ...
}

编辑解决方案:

问题在于标记为“1”的行和调用验证 我对这些行使用了不正确的上下文。

在:

mockContext.Setup(x => x.TestCaseExecutions.Add(It.IsAny<TestCaseExecution>())).Callback(() => addExecution++); //1

后:

mockTestCaseExecution.Setup(x => x.Add(It.IsAny<TestCaseExecution>())).Callback(() => addExecution++);

最后一行的验证方法也是如此。

1 个答案:

答案 0 :(得分:2)

1行上你设置了模拟,但是行2会覆盖整个模拟,所以现在mockContext.TestCaseExecutions会返回mockTestCaseExecution.Object - 模拟还没有构造

您在Add对象上调用mockTestCaseExecution,因此您应该在那里进行设置。

//Mock of one of it's tables
var mockTestCaseExecution = new Mock<DbSet<TestCaseExecution>>();
mockTestCaseExecution.Setup(x => x.Add(It.IsAny<TestCaseExecution>())).Callback(() => addExecution++); //1

mockContext.Setup(c => c.TestCaseExecutions).Returns(mockTestCaseExecution.Object); //2