Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a right case for Mockito spy?

Let's say I have a class

class SomeClass
{
  public void methodA()
  {}

  public void methodB()
  {}

  public void someMethod()
  {
     methodA();
     methodB();
  }
}

I would like to test behavior of someMethod() with Mockito.

The only way I could think of is using spy();

Something like

SomeClass someClass = spy(new SomeClass());
someClass.someMethod();
InOrder inOrder = inOrder(someClass);
inOrder.verify(someClass).methodA();
inOrder.verify(someClass).methodB();

I'm new to the mockito and documentation says

"Real spies should be used carefully and occasionally, for example when dealing with legacy code."

So maybe I'm missing something and there is better (right) way to verify that methodA and methodB were called without explicitly calling them in the test case.

Thanks.

like image 548
ank Avatar asked Sep 11 '10 20:09

ank


People also ask

When should a spy be used in Mockito?

A Mockito spy is a partial mock. We can mock a part of the object by stubbing few methods, while real method invocations will be used for the other. By saying so, we can conclude that calling a method on a spy will invoke the actual method, unless we explicitly stub the method, and therefore the term partial mock.

When should a spy be used?

Spies are useful when we have a huge class full of methods, and we want to mock certain methods. In this scenario, we should prefer using spies rather than mocks and stubs. It calls the real method behavior, if the methods are not stubbed.

Why do we use spy in Mockito?

Mockito. spy() is a recommended way of creating partial mocks. The reason is it guarantees real methods are called against correctly constructed object because you're responsible for constructing the object passed to spy() method.

Does Mockito spy call real method?

A mock does not call the real method, it is just proxy for actual implementations and used to track interactions with it. A spy is a partial mock, that calls the real methods unless the method is explicitly stubbed. Since Mockito does not mock final methods, so stubbing a final method for spying will not help.


2 Answers

Yes, spy() is fit for your purpose. The warning is due to the fact that real methods are invoked, and hence you can get unexpected results (for example - real money being withdrawn from a bank account)

like image 99
Bozho Avatar answered Oct 12 '22 16:10

Bozho


If your code needs spy for unit testing - something wrong. Spy is a first sign of a code smell. You have two options to avoid it in your example:

  1. You can avoid mocking one of the method and test the whole someMethod.
  2. If methodA and methodB is really needs to be mocked - you can move them to seperate class etc.
like image 38
Alexander Bezrodniy Avatar answered Oct 12 '22 15:10

Alexander Bezrodniy