Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue Using Mockito's When Method

Tags:

java

mockito

I'm struggling trying to teach myself Mockito.

Consider the following method, hasInventory(), which should not really run in my way of thinking, but get set up to return true or false as I squirrel-cage my test. Class Warehouse is my "mocked-dependency".

public class Warehouse implements IWarehouse
{
  private Map< String, Integer >    inventory;

  public Warehouse()
  {
    this.inventory = new HashMap< String, Integer >();
  }

  public final boolean hasInventory( String itemname, int quantity )
      throws InventoryDoesNotExistException
  {
    if( inventory == null )
      throw new InventoryDoesNotExistException();

    if( !inventory.containsKey( itemname ) )
      return false;

    int current = ( inventory.containsKey( itemname ) ) ? inventory.get( itemname ) : 0;

    return( current >= quantity );
  }
  ...

In the JUnit test code, the first when() throws an exception because it literally interprets the method call (executing it) and, inventory being nil (see above), InventoryDoesNotExistException is thrown. There are other methods in the mocked-dependency class too, like add() and remove().

@RunWith( MockitoJUnitRunner.class )
public class OrderInteractionTest
{
  private static final String TALISKER = "Talisker";
  private Order   systemUnderTest  = null;

  @Mock
  private Warehouse   mockedDependency = null;

  @Before
  public void init()
  {
    //MockitoAnnotations.initMocks( this );
    //mockedDependency = mock( Warehouse.class );
    this.systemUnderTest  = new Order( TALISKER, 50 );
  }

  @Test  
  public void testFillingRemovesInventoryIfInStock()  
  {  
    try  
    {  
      doNothing().doThrow( new RuntimeException() ).when( mockedDependency ).add( anyString(), anyInt() );  
      doNothing().doThrow( new RuntimeException() ).when( mockedDependency ).remove( anyString(), anyInt() );  
      when( mockedDependency.hasInventory( anyString(), anyInt() ) ).thenReturn( true );  
      when( mockedDependency.getInventory( anyString() ) ).thenReturn( 50 );

As I understand it, by the when() method, I'm asking Mockito precisely not to call hasInventory(), but just to return true instead whenever it's called as I test the class ("systemUnderTest"). Can anyone help me get past this point (or get some sense into my brain)?

I'm linking mockito-all-1.8.5.jar and JUnit 4.

Copious thanks to all who read this.

Russ

like image 640
Russ Bateman Avatar asked Sep 28 '11 14:09

Russ Bateman


People also ask

What is the use of Mockito when?

Mockito is a mocking framework, JAVA-based library that is used for effective unit testing of JAVA applications. Mockito is used to mock interfaces so that a dummy functionality can be added to a mock interface that can be used in unit testing.

Does mock object call real method?

In the given statement the real function kit. getResource() is called which leads to an NPE since function calls on resources are not mocked.

Can we mock method of same class?

We can mock runInGround(String location) method inside the PersonTest class as shown below. Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing. Then we can mock the method we want as follows.

How do I know if Mockito is working?

Mockito verify() method can be used to test number of method invocations too. We can test exact number of times, at least once, at least, at most number of invocation times for a mocked method. We can use verifyNoMoreInteractions() after all the verify() method calls to make sure everything is verified.


1 Answers

Mockito cannot mock final classes or methods. Try removing the final modifier from the hasInventory method. Or better yet, do not mock the Warehouse class, instead mock the IWarehouse interface, whose methods cannot be final, and presumably defines those used by Order.

In general, it's preferable to mock interfaces, but it's not mandatory.

Not being able to mock final classes or methods is briefly mentioned in the Mockito FAQ, it is due to the runtime class generation technique used for creating the mocks.

like image 152
Grundlefleck Avatar answered Oct 11 '22 19:10

Grundlefleck