Reputation: 186
I have the following problem while UnitTesting C# code with Moq framework:
I'm unable to check how many times given method(TestCaseExecutions.Add()) is executed. Execution counter is always zero.
Under "PROBLEM IS HERE" comment there are two lines marked as "1" and "2".
"1" is responsible for iterating TestCaseExecutions.Add(TestCaseExecution) call counter.
"2" is needed for operations on this table in method SomeMethodThatUsesMockedContext(mockContext.Object), without it any linq queries will throw null pointer exception.
After commenting out "2" line and SomeMethodThatUsesMockedContext method and adding
mockContext.Object.TestCaseExecutions.Add(new TestCaseExecution());
just before Verify method resulted with PASS.
How do I get around this problem and why using line "2" somehow neutralizes line "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.
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.
Upvotes: 0
Views: 1022
Reputation: 4394
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.
You call Add
on mockTestCaseExecution
object, so you should set up there.
//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
Upvotes: 2