6

Does NSubstitute have an equivalent to MOQ's VerifyAll call? I'd like to verify that all calls I expect to be received across all substitutes are actually called, ideally in a single TearDown method. I'm currently verifying each received call individually in tests, which isn't ideal. For starters, any calls that are set up on the substitute but that then don't actually get called would slip through the net if they weren't explicitly verified individually.

levelnis
  • 7,665
  • 6
  • 37
  • 61
  • 2
    As pointed out in several answers, NSub isn't really designed to support this. If you are really keen, a very clumsy way of replicating it is to use `ReceivedCalls()`: https://groups.google.com/group/nsubstitute/browse_frm/thread/1d1937eccdec2d0?tvc=1&q=receivedcalls If you need this frequently you are probably best off sticking with Moq or Rhino Mocks. – David Tchepak Feb 07 '13 at 13:51

3 Answers3

7

What you're describing is the behavior of a Strict mock. Strict mocks, by definition, only allow things you explicitly configure and expect. This creates very brittle tests that tend to break very often, as your code changes, therefore the use if strict mocks are discouraged, and not supported at all by newer frameworks, such as NSubstitute or FakeItEasy.

I'd suggest simply creating two tests for each one of the methods you need to verify: a test that verifies that a certain method was called, then another, that under the same scenario verifies that other method was not called. Thus, in case your logic changes, and one of the methods is called/not called when it should, you'll only get one test broken.

Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
  • 5
    "This creates very brittle tests that tend to break very often, as your code changes..." means that strict mocks are doing their job! They're encouraging you to simplify interactions between objects, which improves stability over time. They do this by highlighting needlessly complicated interactions, which make tests brittle, and so on. – J. B. Rainsberger Feb 07 '13 at 14:43
  • 4
    With respect, I disagree. If you follow traditional TDD way, then you should not have to rely on a "catch-all" feature to detect when the flow changes, you rather add new tests that verify new interactions. If you add a new conditional call, for example, and one of the tests you previously wrote broke because of it, you can fix it by adding the new condition logic. Imagine all tests failed all the time after adding one more call. That's why they're called brittle, since they can potentially break after a simple change you might not care about. – Igal Tabachnik Feb 07 '13 at 19:47
  • 2
    I don't understand how your comment relates to my comment. I don't rely on a "catch-all" feature in the way you describe. I often fix brittle tests by simplifying the interactions in production code, instead of making the mocks less strict. I see that as a benefit of strict mocks. That is my point. As for "following traditional TDD way", I do. I helped popularise "traditional TDD way". :) – J. B. Rainsberger Oct 27 '13 at 20:40
6

NSubstitute is meant for AAA style tests, not for Record/Replay. As such, it doesn't support them.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • I'm using it following the AAA style. Even following this style there's value to being able to validate all methods that you expect to be called on your substitute without having to explicitly check each one. If you forget to validate one it dilutes the meaning of the test a little. – levelnis Feb 07 '13 at 11:51
  • 1
    @levelnis: Only in Record/Replay you have to explicitly specify all methods that will be called by your SUT. In AAA, you don't have to do this, so there is no way a `VerifyAll` can work. – Daniel Hilgarth Feb 07 '13 at 11:52
  • Sure, you don't have to do this, but without being able to verify all calls, including those that you've set up but forgotten to remove at a later time as a result of refactoring or whatever else, or because you're not as diligent at clearing up your expectation calls as you should be, it's possible to write passing tests with method calls that are tracked by a substitute but that don't actually get called. I would argue that those tests should fail. In an ideal world we would all be diligent enough to negate against this but having that catch-all check would help with this. – levelnis Feb 07 '13 at 11:59
  • @levelnis: You asked if it is possible with NSubstitute: It is not. Second, I don't see why a test should fail because a method has been setup on a substitute and the SUT doesn't call that method. If that method is not relevant for your test, there is no reason for it to fail. On the other hand, if that method is relevant, you would explicitly be checking it and the test *would* fail, if you refactored the SUT to not call it but forgot to adjust the test. – Daniel Hilgarth Feb 07 '13 at 12:02
  • That's fair enough Daniel. My only concern is about keeping the test code as lean as possible by ensuring that there's nothing there that isn't relevant. I just need to get used to thinking about constructing my tests in a slightly different way. Thanks for your input – levelnis Feb 07 '13 at 12:14
  • 2
    @levelnis: Lean tests are a good thing. But communicative tests are even more important. What do you think communicates better what is expected: `substitute.VerifyAll()` or `substitute.Received.Foo(42)`? – Daniel Hilgarth Feb 07 '13 at 12:17
5

I know this is pretty old and I'm not sure which side I fall in on Loose vs Strict, but for NSubstitute, you can achieve this the following way (xUnit style):

Assert.Empty(_logger.ReceivedCalls());

It shows you all the received calls a particular mock has, so you can just ensure that this number is 0. This may be a newer feature than before, but wanted to make sure it was out there! :)

Daniel Lorenz
  • 4,178
  • 1
  • 32
  • 39