简体   繁体   English

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

[英]Verifying if method was called with Moq

I have the following problem while UnitTesting C# code with Moq framework: 在使用Moq框架进行单元测试C#代码时,我遇到以下问题:

I'm unable to check how many times given method( TestCaseExecutions.Add() ) is executed. 我无法检查给定方法( TestCaseExecutions.Add() )执行了多少次。 Execution counter is always zero. 执行计数器始终为零。

Under "PROBLEM IS HERE" comment there are two lines marked as "1" and "2". 在“这里有问题”注释下,有两行标记为“ 1”和“ 2”。

"1" is responsible for iterating TestCaseExecutions.Add(TestCaseExecution) call counter. “ 1”负责迭代TestCaseExecutions.Add(TestCaseExecution)调用计数器。
"2" is needed for operations on this table in method SomeMethodThatUsesMockedContext(mockContext.Object) , without it any linq queries will throw null pointer exception. 方法SomeMethodThatUsesMockedContext(mockContext.Object)中对此表的操作需要“ 2”,否则,任何linq查询都将引发空指针异常。

After commenting out "2" line and SomeMethodThatUsesMockedContext method and adding 注释掉“ 2”行和SomeMethodThatUsesMockedContext方法并添加后

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

just before Verify method resulted with PASS. 验证方法通过PASS之前。

How do I get around this problem and why using line "2" somehow neutralizes line "1"? 我如何解决此问题,为什么使用行“ 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());

    ...
}

EDIT WITH SOLUTION: 使用解决方案进行编辑:

Problem lies in line marked as "1" and in calling of Verify. 问题在于标记为“ 1”的行和调用Verify。
I have used incorrect context for these lines. 我为这些行使用了错误的上下文。

Before: 之前:

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

After: 后:

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

Same goes for Verify method in the last line. 最后一行的验证方法也是如此。

On the line 1 you setup the mock, but line 2 overrides the whole mock, so now mockContext.TestCaseExecutions returns mockTestCaseExecution.Object - mock that hasn't been configured. 在第1行上,您设置了模拟,但第2行覆盖了整个模拟,因此,现在模拟mockContext.TestCaseExecutions返回了模拟mockContext.TestCaseExecutions mockTestCaseExecution.Object尚未配置的模拟。

You call Add on mockTestCaseExecution object, so you should set up there. 您在mockTestCaseExecution对象上调用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM