验证是否使用 Moq 调用了方法

本文关键字:调用 方法 Moq 是否 验证 | 更新日期: 2023-09-27 18:31:40

在使用Moq框架对C#代码进行单元测试时,我遇到了以下问题:

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

在"问题在这里"注释下,有两行标记为"1"和"2"。

"1"负责迭代TestCaseExecutions.Add(TestCaseExecution)调用计数器。
在方法 SomeMethodThatUsesMockedContext(mockContext.Object) 中对此表的操作需要"2",如果没有它,任何 linq 查询都将引发空指针异常。

在注释掉"2"行和一些使用模拟上下文方法的方法并添加

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

就在验证方法产生 PASS 之前。

我如何解决这个问题,为什么使用行"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"的行和调用 Verify 上。
我对这些行使用了不正确的上下文。

以前:

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

后:

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

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

验证是否使用 Moq 调用了方法

在设置

模拟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