156

What is the purpose of Verifiable()?

If I verify a Mock and leave this out it still verifies the SetUp.

Edit: I was using VerifyAll() thus the reason for everything being verified. After changing to Verify() only my .Verifiable() SetUps were being checked.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Castrohenge
  • 8,525
  • 5
  • 39
  • 66

2 Answers2

104

ADDENDUM: As the other answer states, the purpose of .Verifiable is to enlist a Setup into a set of "deferred Verify(...) calls" which can then be triggered via mock.Verify().

The OP's clarification makes it clear that this was the goal and the only problem was figuring out why it wasn't working, but as @Liam prodded, the answer should really touch on this too:- The key use cases as far as I can see are:

  • maintaining DRYness between a mock.Setup() and mock.Verify
  • allowing one to disconnect the configuring of a verification from the actual Verify call itself (e.g., you could set it up in another helper method)

... and back to my answer, which tersely effectively says "be careful as the above pros are commonly considered to be outweighed by the effect that achieving those goals has on the legibility and maintainability of tests which lean too much on such constructs"

ORIGINAL: Note that where possible, one should instead follow the AAA layout and hence one should be doing explicit mock.Verify( expression ) calls after the work has been done, rather than a mock.Setup( ... ).Verifiable() paired with a mock.Verify() or mock.VerifyAll() wherever possible (credit: @kzu).

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
  • To clarify -- If I need a mock to return something to the code under test, is that a case where `Setup(...)` (in my arrange section) and `VerifyAll()` (in my assert section) would be appropriate? – Eric Smith Feb 14 '12 at 19:31
  • 8
    @EricSmith Looking back, don't think I put it strongly enough. There is massively more benefit from splitting your work into AAA bundling than overconcentrating on commonalities between the Arrange and Assert phase. 90% of the time, there's something to be gained from the nuances of how you express the Verify calls at the end, so you should take a lot of time to optimize for that, even if in some cases if seems like some painful duplication. One of the points http://manning.com/osherove makes very well is that making a test make sense to somebody jumping in is critical -so stick to convention! – Ruben Bartelink Feb 14 '12 at 20:54
  • 5
    I'm not normally one to go against the grain of accepted wisdom but am as yet unconvinced of the benefits of AAA vs `Verifyable()`/`VerifyAll()` in all cases. My current unit test has a large number of `Setup(...)` calls (>30). Could match each one with an equivalent Verify() to satisfy convention but this causes a large amount of code duplication and will be trickier to maintain and read as the number of unit tests grows. I guess what I'm really asking is can exceptions be made if there are a large number of Setups or is the avoidance of `Verifiable()` a hard and fast rule? – Steve Chambers May 08 '13 at 09:21
  • 5
    @SteveChambers A key element of AAA is that it's not A* -- there should be a single Act and a single Assert. So while you are technically correct in saying that it is less code for you, the coincidences of which of your Setups apply to which (sub)Acts and (sub)Asserts will invariably become a minefield. So no, it's not hard and fast, but I would say that suggesting that it's even close to 50:50 would be Very Bad Advice. (Also note that you don't need to do a Setup to do a Verify unless you're trying to introduce a particular behavior during the Act- which is yet another element of clear tests) – Ruben Bartelink May 08 '13 at 11:40
  • Though an interesting discussion on best practice on unit testing, this doesn't really answer the question. The question was "What is the purpose of Verifiable()?". to which you've said "you shouldn't really use it". For those that having read this, still want to use it though (which they are well within their rights to do) this answer doesn't really help. – Liam Oct 30 '15 at 09:30
  • @Liam The answer in that's case is to simply upvote Suvesh's answer. As for the pedantics of SO, the OP asks *what is the purpose*, which for me suggests that they may be open to a broader answer just that "it connects the frob to the frog". NB it wasnt too long before this answer that I'd done the same search and ended up in the comments of a thread on the Moq repo which I linked to which made me realise "I'm thinking about it wrong", which instantly spoke to me in the same way it likely speaks to others too - hence the accept and the upvotes. – Ruben Bartelink Oct 30 '15 at 11:11
  • 1
    @Liam And it *is* indeed totally fine that you're still convinced it's an appropriate tool for your job - my real point is just that it's frowned upon as a general approach to writing tests with mocks - i.e. despite the fact that it neatly achieves DRYness between a `Setup` and a `Verify`, that may be missing a higher win achievable only be relaxing the DRY constraint in the manner suggested by AAA and the family of strategies that strongly implies – Ruben Bartelink Oct 30 '15 at 11:15
  • Yep, don't get me wrong, I agree. I just felt it slightly missed the point of the question. I found it very interesting anyway! – Liam Oct 30 '15 at 11:20
  • 1
    @Liam Thanks for the prodding; I updated my answer because you are correct in the point you're making. Back in the day when I answered SO questions like this, my view was generally to succinctly state an atomic answer and then let competing answers like the other one fill out the map. These days (if I still took the time to answer questions) I'd likely try to give the more complete answer that this has become in the first instance. – Ruben Bartelink Oct 30 '15 at 11:24
  • All Google C++ code setups the mocks (and their assertions) before "Acting". This saves duplicate code, and solves many management lifetime issues AAA suffers from. So I think it's safe to say that many top developers have chosen a different approach than AAA. https://google.github.io/googletest/gmock_for_dummies.html#using-mocks-in-tests – AffluentOwl Mar 15 '23 at 17:23
68

When the Verify() method is called at the end of the test, if any of the expectations marked as verifiable have not been called, then an exception is thrown.

VerifyAll() does not check for verifiable expectations.

Ankush Madankar
  • 3,689
  • 4
  • 40
  • 74
SuPra
  • 8,488
  • 4
  • 37
  • 30