Export to GitHub

mockito - issue #84

high performance mocks


Posted on May 17, 2009 by Massive Monkey

Allow the framework to create high-performance mocks. For example stub-only mocks that don't store invocations for verification. Or mocks without clickable stack trace location.

Example TestCase:

public class MockitoTestCase extends TestCase {

MockitoTestCase() { super("testIt"); }

public static TestSuite suite() { TestSuite suite = new TestSuite(); for (int i=0; i < 5000; i++) suite.addTest(new MockitoTestCase()); return suite; }

public void testIt() { List mockList = Mockito.mock(LinkedList.class); Mockito.when(mockList.get(0)).thenReturn("hi"); for (int i=0; i < 20000; i++) mockList.get(0);

   // memory is consumed without this call
   // (even though the object is going out of scope)
   Mockito.reset(mockList);

}

Comment #1

Posted on Jul 9, 2009 by Massive Monkey

(No comment was entered for this change.)

Comment #2

Posted on Oct 28, 2009 by Happy Dog

+1. I do a lot of stubbing and spying where I'm not interested in verification, and this could be a nice enhancement.

Comment #3

Posted on Nov 11, 2009 by Massive Monkey

(No comment was entered for this change.)

Comment #4

Posted on Jan 26, 2010 by Happy Dog

Just a followup on this - having a mockSetting for this would be fine.

Comment #5

Posted on Apr 27, 2010 by Quick Bear

Comment deleted

Comment #6

Posted on Apr 27, 2010 by Quick Bear

+1. I think this would be nice too when I am not interested in verification. Which is more often than not... just mocking out constructor injected dependencies.

Comment #7

Posted on Apr 27, 2010 by Massive Monkey

If you like it then please provide a patch ;)

Comment #8

Posted on Apr 28, 2010 by Quick Bear

How should the api look? I am not too sure of all the use cases. Should we make it explicit per mocked class, with some way of saying Mockito.mockOnly(X.class) or Mockito.liteMock(X.class), or...? Any ideas on how this should look?

Comment #9

Posted on Apr 29, 2010 by Massive Monkey

Hey,

Thanks for looking at it!

  1. The api should not introduce new static method on Mockito class. Ideally it should be addition to withSettings(). So basically it should be configured per mock.
  2. We should have some proof those mocks are really faster
  3. They should either not allow verification (easier) or not store the clickable stacktrace (bit harder - we have to make sure the verification still works).

Comment #10

Posted on May 1, 2010 by Quick Bear

Even with 3> I dont find it as easy...:) where is appropriate place to check the setting.isVerifiable and to error out preventing the verification?

Should I add a new check of the setting & reporter.someMessage inside verify(), verifyNoMore..() methods on MockitoCore. Or is a broader refactoring needed in that area?

Comment #11

Posted on May 4, 2010 by Massive Monkey

where is appropriate place

find it :) It will be easier if you start by just making it work

Should I add a new check of the setting & reporter.someMessage inside verify()

Not sure what is the best approach. We need to figure out whether we should not store invocations at all or simply not storing stack trace is enough to have 'high peformance' mocks.

I think it is best to start with some test/demo and then try to fix it.

Comment #12

Posted on May 4, 2010 by Quick Bear

interesting approach. I thought I could leverage someone who already knew the code base. I will take another look when I have a bit of time. :) Cheers

Comment #13

Posted on Aug 27, 2010 by Helpful Ox

I find it useful to have lite mocks in some cases. I have a case in which because mocks are heavy weight, it crashes with either timeout or OOME (because there are too many arguments passed to a method).

Cheers

Comment #14

Posted on Aug 30, 2010 by Helpful Bear

After spending some time on the codebase, I'm not sure that not storing invocations would fasten things. The real overhead seems to come from proxying.

Comment #15

Posted on Aug 30, 2010 by Helpful Bear

My bad. I finally found where the stacktrace computation code is and removing it a real accelerator.

Comment #16

Posted on Aug 30, 2010 by Helpful Bear

Here is the code for stubOnly mocks that don't remember invocation locations and that cannot be verified. Using this king of mocks is 2 to 10 times faster.

I attached the source code and here is the commit on github: http://github.com/dgageot/Mockito/commit/33ee545a57a72207acabd7901f116aeae562749c

What do you think?

Attachments

Comment #17

Posted on Aug 30, 2010 by Helpful Bear

Here is another change that improves mock invocation time by a factor of two. http://github.com/dgageot/Mockito/commit/b050792ea0785a621058fb292a9061b1350da655

This replaces my previous proposition of stubOnly mocks with a much simpler solution that work on every mock.

The idea is to improve the code that does StackTrace capturing and filtering.

Comment #18

Posted on Sep 2, 2010 by Massive Monkey

good stuff!

So basically it does not make much sense to implement stub-only mocks? The second enhancement seems to give us enough boost, right?

Thanks :)

Comment #19

Posted on Sep 2, 2010 by Helpful Bear

Exactly.

Comment #20

Posted on Oct 12, 2010 by Helpful Bear

Finally pushed a patch to a clone. Should be easier to apply. Tried to request for a code review but didn't manage to make it work.

http://code.google.com/r/dgageot-mockito/source/detail?r=3af40aaa724ac31a7e46ff1539d90aa5792e2a1e

Comment #21

Posted on Oct 15, 2010 by Quick Dog

Can I vote for dgageot's first enhancement please?

As per my post on the mailing list (http://groups.google.com/group/mockito/browse_thread/thread/2bd28d51853310b6), I'm more interested in memory usage, than in speed. I'd like to be able to make stub-only mocks. There are certain points in my performance tests where I can't use regular mocks, without running out of heap space.

Kind regards, David Wallace.

Comment #22

Posted on Oct 16, 2010 by Massive Monkey

@dgageot, your performance improvement is merged. Thanks a lot. I put it in a separate entry (see issue 226)

Comment #23

Posted on Nov 7, 2010 by Massive Monkey

(No comment was entered for this change.)

Comment #24

Posted on Oct 17, 2011 by Happy Panda

I've got the same issue as David Wallace: My mocks are running out of memory. I'm currently writing stubs by hand to get around that :(

I'd REALLY appreciate mocks that don't use memory.

Comment #25

Posted on Oct 23, 2011 by Massive Monkey

Niko - have you tried using the reset method within the loop that runs your tests? Karl Schaefer recommended this when I first raised the issue on the mailing list, a little over a year ago.

Unfortunately, it seems that reset wipes out the stubbing information as well as the verification information, so you need to re-stub everything whenever you use it. However, I've found this slightly less annoying than using manual (non-Mockito) stubbing.

Hopefully (please, Szczepan), the next release of Mockito will EITHER contain dgageot's patch for stub-only mocks OR a method similar to reset, that would wipe out the verification information of a mock, without resetting the stubbing.

Either one of these features would make volume testing with Mockito a whole lot less painful.

Comment #26

Posted on Oct 23, 2011 by Happy Horse

Hey,

Try the 1.9.0-rc1, it includes the stacktrace performance improvement. As this RC is quite stable, albeit a few changests to merge, we will probably make a final release soon.

Comment #27

Posted on Oct 23, 2011 by Massive Monkey

Thanks Brice, I've been using 1.9.0-rc1. But the stacktrace performance improvement doesn't resolve the heap space issue. I really want a Mockito release that has the other patch that dgageot submitted - see my earlier comment (number 21). I'm hoping it will be included in 1.10.0.

Regards, David.

Comment #28

Posted on Oct 23, 2011 by Happy Horse

Comment deleted

Comment #29

Posted on Oct 23, 2011 by Happy Horse

Well I wont promise this patch will ever make its way in the next release. While the patch that David Gageot proposed is well crafted and matches our way of doing things, it mostly avoid the stacktrace computation cost with heavier changes the code structure.

However I understand your need, but it might need some investigation for better ways of doing it. For exemple CGLIB which we use internally is also known to clutter the PermGen on a Sun JVM. It is generally not a big issue in tests, but if you aleady have problems with your memory this can be visible in your case.

Comment #30

Posted on Oct 24, 2011 by Massive Monkey

Thanks, Brice. I do appreciate the team's consideration in this regard. I also realise that I'm just one Mockito user among many thousands, and that I'm not going to get every feature that I want :-) I just think it would be a shame if this issue disappeared off the team's radar.

Thanks again, David.

Comment #31

Posted on Oct 24, 2011 by Massive Monkey

Let's implement it (or accept a patch from an eager contributor :) It's cheap enough and if we do it via withSettings() we don't clutter the core api.

We're going to need a separate issue for it. Also when implementing this we might think a little bit if it makes sense to expose some lower level api for this area (e.g. some new stuff to the MockitoConfiguration that exposes some internalities around remembering invocations, stack trace processing, etc.).

Comment #32

Posted on Oct 24, 2011 by Quick Giraffe

Today, org.mockito.internal.verification.RegisteredInvocations blew the heap of an 8GB java process we were running. It was a mass test data generating process that uses most parts of our enterprise application but replaces a component (Spring service) with a mock. The "real" component sends out emails, which we didn't want to do here.

One could argue that we are misusing mockito here, because we are not interested in any specific calls to the mock at all and we just want the dependency injection to work. But having the ability to create a "high performance mock" with regard to a minimal heap consumption would definitely be helpful for our setup.

Comment #33

Posted on Oct 25, 2011 by Happy Horse

Agreed it should not only avoid stackstrace computation, but avoid entirely the invocations registration.

Also for some internal stuff, it might be interesting to provide such an API in the mockito configuration, for example we can now enable/disable the objenesis cache.

Comment #34

Posted on Oct 25, 2011 by Massive Monkey

it might be interesting to provide such an API in the mockito configuration, for example we can now enable/disable the objenesis cache.

Yeah! I also think I would like to try to keep the MocktioConfiguration API a more lower level api, rather than copying all the mock's withSettings() stuff. Those are just brainstorming-kind of thoughts, though :)

Comment #35

Posted on Oct 25, 2011 by Massive Monkey

I also think I would like to try to keep the MocktioConfiguration API a more lower level api

For example, a withSettings() could have a 'stubOnly' settings. MockitoConfiguration could have a stack trace processor thingy. Just thinking loud...

Comment #36

Posted on Jul 24, 2012 by Swift Rabbit

+1. I would very much appreciate the stubOnly settings on the mocks. Mockito offers great way of partial implementation of interfaces for test purposes. Not having stubOnly option however disqualifies it from using these mocks: when there are thousands of invocations of mocked methods, mockito quickly goes out of memory.

I can help in implementing this feature if anyone points me to the right place. I might be overlooking some things, but is it harder than adding MockSettings.stubOnly() and checking the value of it before captureArgumentsFrom() is called in MockHandler?

Comment #37

Posted on Sep 3, 2012 by Happy Horse

(No comment was entered for this change.)

Comment #38

Posted on Sep 3, 2012 by Happy Horse

(No comment was entered for this change.)

Comment #39

Posted on Sep 25, 2014 by Massive Bear

Why is this never released?

Thanks!

Comment #40

Posted on Sep 25, 2014 by Massive Monkey

Sandra, I don't know. As you can see, I asked for it in October 2010 and Szczepan seems to have agreed to it in October 2011. I would still find this really useful, and it seems that others have asked for it too. Once again, Brice or Szcepan, please can we have some action on this. I never really understood your reservations with David Gageot's original patch. What is there still to do on this? And if there's real work still to be done, can I help in any way?

Comment #41

Posted on Sep 25, 2014 by Massive Monkey

(No comment was entered for this change.)

Comment #42

Posted on Sep 25, 2014 by Massive Monkey

Thank you Szczepan. That makes me very happy.

Comment #43

Posted on Sep 30, 2014 by Happy Horse

Note this was in the master since almost one year already. stubOnly is only a topic among many others to be the only subject of this issue.

Status: Fixed

Labels:
Type-Enhancement Priority-Medium Milestone-Release1.10.0