# Mocking Annotations

## Using `@InTestsMock`

Perhaps you have a method that Diffblue Cover would ordinarily test using an `Integer` but you'd prefer to see it tested using `Mockito.mock(..)`. In this case you could annotate the method (or class, or package) to recommend mocking `Number`:

```java
public class ClassUnderTest {
  @InTestsMock(Number.class)
  public static String methodUnderTest(Number number) {
    return String.valueOf(number.intValue());
  }
}
```

#### Setting the priority of the annotation

There are various levels of priority that can be specified for the `@InTestMock` annotation. The enum `MockDecision` is provided by the Diffblue Cover Annotation library and can be set to the following values for the \`decision' attribute. This attribute is optional and will default to `MockDecision.RECOMMENDED` if unset.

| Value                                | Description                                                                                                                     |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `MockDecision.REQUIRED`              | The class will be mocked at the highest priority, non-mocks may be provided if they provide more coverage.                      |
| `MockDecision.RECOMMENDED` (default) | The class should be mocked at a high priority, non-mocks may be provided if they provide more coverage.                         |
| `MockDecision.ALLOWED`               | Diffblue Cover will try to create an instance of the class itself, if it is unable to, Diffblue Cover will fallback to mock it. |
| `MockDecision.FORBIDDEN`             | Diffblue Cover will not try to mock this class.                                                                                 |

For example, if Diffblue Cover normally mocks a particular class, but there is a specific location where it should not do so, you can forbid mocking in that location.

```java
public class ClassUnderTest { 
  @InTestsMock(value = Number.class, decision = MockDecision.FORBIDDEN)
  public static String methodUnderTest(Number number) {
    return String.valueOf(number.intValue());
  }
}
```

### Suggesting values to return

When mocking a class, it can be useful to provide Diffblue Cover with suggested values that each method can return. This can be achieved using the following (optional) attributes:

<table><thead><tr><th width="200">Attribute name</th><th width="298.5">Description</th><th>Example usage</th></tr></thead><tbody><tr><td><code>method</code></td><td>The simple name of the method to mock</td><td><code>method = "intValue"</code></td></tr><tr><td><code>booleanReturnValues</code></td><td>The boolean value (or an array of values) to return</td><td><code>booleanReturnValues = true</code> or <code>booleanReturnValues = {true,false}</code></td></tr><tr><td><code>byteReturnValues</code></td><td>The byte value (or an array of values) to return</td><td><code>byteReturnValues = (byte) 1</code> or <code>byteReturnValues = {(byte) 1,(byte) 0}</code></td></tr><tr><td><code>charReturnValues</code></td><td>The char value (or an array of values) to return</td><td><code>charReturnValues = 'A'</code> or <code>charReturnValues = {'A','B'}</code></td></tr><tr><td><code>intReturnValues</code></td><td>The int value (or an array of values) to return</td><td><code>intReturnValues = 2</code> or <code>intReturnValues = {2,3}</code></td></tr><tr><td><code>shortReturnValues</code></td><td>The short value (or an array of values) to return</td><td><code>shortReturnValues = 3</code> or <code>shortReturnValues = {3,4}</code></td></tr><tr><td><code>longReturnValues</code></td><td>The long value (or an array of values) to return</td><td><code>longReturnValues = 4L</code> or <code>longReturnValues = {4L,5L}</code></td></tr><tr><td><code>floatReturnValues</code></td><td>The float value (or an array of values) to return</td><td><code>floatReturnValues = 5.0f</code> or <code>floatReturnValues = {5.0f,6.0f}</code></td></tr><tr><td><code>doubleReturnValues</code></td><td>The double value (or an array of values) to return</td><td><code>doubleReturnValues = 6.0d</code> or <code>doubleReturnValues = {6.0d,7.0d}</code></td></tr><tr><td><code>stringReturnValues</code></td><td>The String value (or an array of values) to return</td><td><code>stringReturnValues = "AAA"</code> or <code>stringReturnValues = {"AAA","BBB"}</code></td></tr><tr><td><code>returnValueFactory</code></td><td>The name of the static method to call to create the required object. The syntax is: fully qualified class name + method name, separated by a dot</td><td><code>returnValueFactory = "com.example.Factory.makeUser"</code></td></tr><tr><td><code>throwException</code></td><td>The class of the exception to throw when the method is called. Must be a subclass of <code>Throwable</code> with an accessible constructor.</td><td><code>throwException = IllegalArgumentException.class</code></td></tr><tr><td><code>throwExceptionFactory</code></td><td>The name of the static method to call to create the exception instance. The syntax is: fully qualified class name + method name, separated by a dot. The method must return a subclass of <code>Throwable</code></td><td><code>throwExceptionFactory= "com.example.Factory.createCustomException"</code></td></tr></tbody></table>

For example, to suggest that Diffblue Cover should return a value of `5` from the mocked method `Number.intValue()` , the following annotation could be used:

```java
public class ClassUnderTest {
  @InTestsMock(value = Number.class, method = "intValue", intReturnValues = "5")
  public static String methodUnderTest(Number number) {
    return String.valueOf(number.intValue());
  }
}
```

To return an object, use a factory method. Diffblue Cover will call the specified static method and use its result as the mocked return value.

```java
public class ClassUnderTest {
  @InTestsMock(
    value = AccountService.class,
    method = "getAccount",
    returnValueFactory = "com.example.Factory.createTestAccount"
  )
  public static String methodUnderTest(AccountService service) {
    return service.getAccount().getId();
  }
}
```

{% hint style="info" %}
Note that values provided for Diffblue Cover to use while mocking will be prioritised, however if Diffblue Cover is unable to create a test, or if it is not able to generate more coverage using the suggested value, the suggestion may not be used.
{% endhint %}

#### Suggesting an array of values

Since a mocked method can only return a single value, why specify an array of values? Diffblue Cover will try to use the values in the order they are specified. The value chosen is the value that provides the best test. In most cases, specifying only a single value will be sufficient for generating a test with good coverage. Not all provided values will be used if Diffblue Cover has already generated a test with good coverage.

### Using multiple `@InTestsMock` annotations

You can specify multiple mocked methods by using the annotation more than once:

```java
@InTestsMock(
  value = UserService.class,
  method = "getName",
  stringReturnValues = {"Alice"}
)
@InTestsMock(
  value = UserService.class,
  method = "getAge",
  intReturnValues = {30}
)
@InTestsMock(
  value = AccountService.class,
  method = "getAccount",
  returnValueFactory = "com.example.Factory.createTestAccount"
)
public boolean isValid(UserService user, AccountService account) {
  return user.getName().length() >= 3
      && user.getAge() >= 18
      && account.getAccount().getId().startsWith("test-");
}
```

#### Precedence when using multiple annotations

When multiple `@InTestsMock` annotations are applied to the same method under test there are a few aspects to understand regarding how Diffblue Cover will utilize the annotations:

* Diffblue Cover will always favor the annotation nearest the method under test. This allows you to define an annotation at the class level, which will affect all methods in the class, and then override specific methods by defining an annotation at the method level.
* The `MockDecision` ('decision') is applied to the `Class` ('value').
  * If the 'decision' is `MockDecision.FORBIDDEN` then the values of 'method' and '\*returnValues' are ignored.
* The various 'returnValues' and 'throwException' attributes are applied to the combination of 'value' (i.e. `Class`) and 'method', and aggregate for a `Class#Method` combination.

Please see the below illustration:

```java
@InTestsMock(
  value = AccountService.class,
  decision = MockDecision.FORBIDDEN,
  method = "getBalance",// This value will be ignored as decision is FORBIDDEN
  intReturnValues = {5} // This value will be ignored as decision is FORBIDDEN
)
@InTestsMock(
  value = UserService.class,
  decision = MockDecision.ALLOWED,
  method = "getName",
  stringReturnValues = {"Alice"}
)
public class ClassUnderTest {

  @InTestsMock(
    value = UserService.class,
    method = "getName",
    stringReturnValues = {"Bob", "Janice"} // In addition to the class level value
  )
  @InTestsMock(
    value = UserService.class,
    decision = MockDecision.REQUIRED, 
    // mocking UserService will be given the highest priority
    method = "getAge",
    intReturnValues = {30}
  )
  @InTestsMock(
    value = AccountService.class,
    // No defined 'decision', AccountService mocking will be RECOMMENDED
    method = "getAccount",
    returnValueFactory = "com.example.Factory.createTestAccount"
  )
  public boolean isValid(UserService user, AccountService account) {
    return user.getName().length() >= 3
        && user.getAge() >= 18
        && account.getAccount().getId().startsWith("test-")
        && account.getBalance() >= 0;
  }
}
```

In the example above, Diffblue Cover will configure how it generates mock objects when writing tests for `ClassUnderTest#isValid` in the following way:

* When generating a `UserService` object Diffblue Cover will use `MockDecision.REQUIRED`
  * When mocking method `UserService#getName` , suggested values "Bob", "Janice" and "Alice" are provided.
  * When mocking method `UserService#getAge` , suggested value 30 is provided.
* AccountService will use `MockDecision.RECOMMENDED`
  * When mocking method `AccountService#getBalance` , mock will be configured to return Diffblue Cover generated values.
  * When mocking method `AccountService#getAccount` , suggested object factory `com.example.Factory.createTestAccount` is provided.

## Using `@InTestsMockConstruction`

Perhaps you have a method that Diffblue Cover is unable to test, and you think it could make more progress using `Mockito.mockConstruction(Random.class)`. In this case, you could annotate the method (or class, or package) to recommend mocking construction of `Random`:

```java
public class ClassUnderTest {
  @InTestsMockConstruction(Random.class)
  public static int methodUnderTest() {
    return new Random().nextInt();
  }
}
```

{% hint style="info" %}
Note that using `@InTestsMockConstruction` has the same effect as, and can be overridden by, Cover CLI command line option:

```
dcover create --mock-construction ClassToMockConstruction
```

{% endhint %}

## Using `@InTestsMockStatic`

Perhaps you have a method that Diffblue Cover is unable to test, and you think it could make more progress using `Mockito.mockStatic(UUID.class)`. In this case, you could annotate the method (or class, or package) to recommend mocking static methods of `UUID`:

```java
public class ClassUnderTest {
  @InTestsMockStatic(UUID.class)
  public static Path methodUnderTest() {
    return Paths.get(UUID.randomUUID() + ".zip");
  }
}
```

{% hint style="info" %}
Note that using `@InTestsMockStatic` has the same effect as, and can be overridden by, Cover CLI command line option:

```
dcover create --mock-static ClassToMockStatic
```

{% endhint %}
