chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
Hi,

Is there a way to verify that a method was called exactly N times?

Isolate.Verify... doesn't seem to provide that.



Thanks,
Andrew
asked by andreister (3.4k points)

8 Answers

0 votes
Hi Andrew,

The AAA API does not provide a built in way to test what you are describing. Generally speaking, this sort of verification may lead to a very fragile test. Can you describe the scenario you are trying to test?

Anyway, this can be done with our older Natural Mocks API - you can see an example here: https://www.typemock.com/Docs/UserGuide/ ... tural.html

Doron
Typemock Support
answered by doron (17.2k points)
0 votes
Doron,

Thanks for the answer - that's pretty much what I expected, just wanted to make sure.

I see what you mean by "a very fragile test" but that's beyond the scope of my question. I use the mentioned scenario for my mocking frameworks compare project http://code.google.com/p/mocking-frameworks-compare and all the other frameworks - Moq, Rhino, Nmock2 and Stubs - does address that case.

Regards,
Andrew
answered by andreister (3.4k points)
0 votes
There is a possible workaround (using WhenCalled(..).DoInstead(action) where you can count the times if you really wanted to, but,
Ultimately, we want it to be harderunnatural to do something like that (so it feels like a test smell)
answered by royo (2k points)
0 votes
While I agree with your comments on the fragile-ness aspect, there have been times when I wanted to verify it was called only once (lazy loading public properties for instance). But I could see scenarios if one were writing caching systems where it could be desireable, but that also feels like a "special case" type of test in which case, using the DoInstead() as you mention seems to be more natural, as you suggest.

Just my $.02
answered by johnminadeo (1.3k points)
0 votes
I want to do something similar: I want to verify that a method was first called with DoWhatever(2) then was called with DoWhatever(3). Is that also considered "fragile?"
answered by MobyDisk (3.6k points)
0 votes
It depends on what exactly you're trying to test. To make sure that your test tests a specific functionality try writing a simple sentence that explains what the test does - if you cannot do that it means that you're trying to test a few aspects that perhaps should be tested in several tests (or not at all.
Another way to make sure that you're not writing a fragile test it to think how easily refactoring could cause your test to fail or make it irrelevant.
To answer your previous question it is possible to check that a method was called with two specific variables:
Isolate.Verify.WasCalledWithExactArguments(() => DoWhatever(2));
Isolate.Verify.WasCalledWithExactArguments(() => DoWhatever(3));

But there is no guarantee of ordering just that the methods were called
answered by dhelper (11.9k points)
0 votes
While I agree with your comments on the fragile-ness aspect, there have been times when I wanted to verify it was called only once (lazy loading public properties for instance). But I could see scenarios if one were writing caching systems where it could be desireable, but that also feels like a "special case" type of test in which case, using the DoInstead() as you mention seems to be more natural, as you suggest.

Just my $.02


I am running into the same scenario mention by johnminadeo. I need to test a method and assert that it only calls the DAL once, any other calls must use the cached result set. I must verify that the DAL is called only once. So, is Natural API the only way to implement this?

Thanks,
Teo
answered by teom (2.3k points)
0 votes
You can use the Natural API or you can create a specific behavior to assert using Doinstead:
int timesCalled = 0;
Isolate.WhenCalled(() => DoSomething).DoInstead(context => timesCalled++);
Assert.AreEqual(1, timesCalled );


Of course you need set similar expectation on other methods that call the DB in order to "count" the times they were being called.

Does that solve your problem?
answered by dhelper (11.9k points)
...