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.Ve开发者_C百科rify(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?
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.
精彩评论