# Mockito CheatSheet: Tldr and Tips

These are some of the useful methods and classes provided by Mockito

### 1. Mockito.mock()

Creates a mock of any class. By default, it will return default value for methods and fields when ***not*** mocked.

For Example:
Primitive data types such as `byte`, `short`, `int`, `long`, `float`, `double`, `boolean` and char will return default value i.e `0` or `false`

Non-primitive data types such as `String`, `Arrays` and `Classes` return `null` when they are not mocked. 

```java
// with annotation
@Mock
private ClassName mock;

// Or with static method
final ClassName mock = Mockito.mock(ClassName.class);

// mock methods that returns something
Mockito.when(mock.sampleMethod()).thenReturn(sampleVal);

// mock method to throw Exception
Mockito.when(mock.sampleMethod()).thenThrow(SampleException.class);

// Mock void methods
Mockito.doNothing().when(mock).method();

// you can get invocation parameters with .thenAnswer()
Mockito.when(mock.sampleMethod(Mockito.any(OtherClass.class))).thenAnswer((Answer<ThirdClass>) invocation -> {
      final OtherClass parameter1 = invocation.getArgument(0);
      return thirdClassObject; 
});

// Verify interactions
Mockito.verify(mock, Mockito.times(1)).sampleMethod();

// Verify, method should not be invoked even once
Mockito.verify(mock, Mockito.never()).sampleMethod2();

// Verify, no methods should be called on given mock
Mockito.verifyNoMoreInteractions(otherMockedClass);
```

### 2. Mockito.spy()

It is similar to *`mock()`* but instead of return default value it will call the actual implementation when ***not*** mocked.

```java
// with annotation
@Spy
private ClassName spy;

// Or with static method
final ClassName spy = Mockito.spy(ClassName.class);

// mock methods that returns something
Mockito.doReturn(value).when(spy).method();

// mock method to throw exception
Mockito.doThrow(new ExceptionClass()).when(spy).metohd();

// mock void methods
Mockito.doNothing().when(spy).method();
```

### 3. Mockito.mockStatic()

Now with Mockito 3, you can mock Classes with static methods.

```java
try (MockedStatic<Foo> dummyStatic = Mockito.mockStatic(ClassName.class)) {
    dummyStatic.when(() -> ClassName.method("param1"))
               .thenReturn("someValue");
    // when
    System.out.println(ClassName.method("param1"));
    //then
    dummyStatic.verify(
            () -> ClassName.method("param1"),
            times(1), 
    );
}
```

### 4. ArgumentMatcher

Basic Rule to match any statement with Mockito is to correctly match its parameters. If any of the parameter did not match then instruction will not be mocked.

```java
// example statement
final int addition = calculator.getAddition(2, 3);

// you have to match exact parameters, in this case (2,3)
Mockito.when(mckCalculator.getAddition(2, 3)).thenReturn(5);

// If you mock for (3,4), you mocked result will not be returned
Mockito.when(mckCalculator.getAddition(3, 4)).thenReturn(5);

// For cases, where you do not know exact parameter then you can use Mockito.anyInt()
Mockito.when(mckCalculator.getAddition(Mockito.anyInt(), Mockito.anyInt())).thenReturn(5);
```

Similarly we have `Mockito.any()`, `Mockito.anyLong()`, `Mockito.anyString()`, `Mockito.anyBoolean()`, `Mockito.anyByte()`, `Mockito.anyChar()`, `Mockito.anyFloat()`, `Mockito.anyDouble()`, `Mockito.anyShort()`, `Mockito.anyList()`,  `Mockito.anySet()` and `Mockito.anyMap()`

### 5. ArgumentCaptor

You can also get value of parameters of mocked methods, you can then Assert for their value.

Below is the same example of calculator class.

```java
// example statement
final int addition = calculator.getAddition(2, 3);

// Create captor
ArgumentCaptor<Integer> argumentCaptor = ArgumentCaptor.forClass(Integer.class);

Mockito.when(mckCalculator.getAddition(argumentCaptor.capture(), argumentCaptor.capture())).thenReturn(5);

final int firstNum = argumentCaptor.getValue();
Assert.assertEquals(2, firstNum);

// You can get second num by calling getAllValues()
final int secondNum = argumentCaptor.getAllValues()[1];
Assert.assertEquals(3, secondNum);
```
