Andy
Andy

Reputation: 2318

Moq and Transactionscope, can you make the moqs not count?

When i'm using a Transactionscope that i don't commmit, moq still sees all the rolled back calls to the database.

Is there a way of doing

_mockRepository.Verify(x => x.InsertSBI(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<String>()), Times.Never());

And not

_mockRepository.Verify(x => x.InsertSBI(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<String>()), Times.Exactly(4));

to make the test succeed?

Upvotes: 0

Views: 1284

Answers (1)

Merlyn Morgan-Graham
Merlyn Morgan-Graham

Reputation: 59101

A couple strategies come to mind.

  • Create a wrapper class for your existing DB access class. Make that wrapper wait to forward any calls to the underlying implementation until you call Commit.

I don't recommend this. It would be a pointless abstraction reserved only for test, because the real DB class (probably) does the same thing under the covers. It will wait to call the DB until Commit is called.

  • Don't try to validate data access this way. Instead validate that Commit wasn't called.

What you're trying to do is stateful testing - you're validating the state of those calls, based on how Commit and Rollback effect them. This is not the right way to go about using mocks.

If you validate that Commit wasn't called, you're testing the high-level behavior of the code that is rolling back the transaction, and its interaction with the DB class. You verify that rollback is called, and that commit isn't called, and trust that it will correctly handle the details.

Something like:

_mockRepository.Verify(x => x.Commit(), Times.Never());
_mockRepository.Verify(x => x.Rollback(), Times.Once());

If you need to verify the DB class itself you can mock out its DB connection and verify that calls don't get made if Rollback is invoked. But you shouldn't do that sort of testing unless you're unit testing that DB class directly.

Upvotes: 3

Related Questions