1. Introduction
In this article, we will show how to Mock classes with generic parameters using Mockito.
2. Test class
The FooService
will be our simple test class with generic parameters:
package com.frontbackend.libraries.mockito.service;
public class FooService<T> {
private T obj;
public T getValue() {
return obj;
}
}
The Car
object will be used for parametrization of the FooService
class:
package com.frontbackend.libraries.mockito.model;
public class Car {
private final Driver driver;
public Car(Driver driver) {
this.driver = driver;
}
public String printWelcome() {
return String.format("Welcome %s!", driver.getName());
}
}
Driver
class is an object injected into the Car
instance:
package com.frontbackend.libraries.mockito.model;
public class Driver {
private final String name;
public Driver(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
3. Using casting
To mock class with generic parameter we could use Mockito mock
method with casting.
package com.frontbackend.libraries.mockito;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.frontbackend.libraries.mockito.model.Car;
import com.frontbackend.libraries.mockito.model.Driver;
import com.frontbackend.libraries.mockito.service.FooService;
import org.junit.Test;
public class MockitoMockClassWithGenericParamTest {
@Test
public void shouldMockGenericService() {
@SuppressWarnings("unchecked")
FooService<Car> mockFoo = (FooService<Car>) mock(FooService.class);
when(mockFoo.getValue()).thenReturn(new Car(new Driver("Mr Bean")));
Car value = mockFoo.getValue();
assertEquals("Welcome Mr Bean!", value.printWelcome());
}
}
In this example, we used Mockito.mock(...)
method to create a mock of FooService
class. Then we cast it to the generic type FooService<Car>
.
Note that there will be a warning:
Unchecked cast: 'com.frontbackend.libraries.mockito.service.FooService' to 'com.frontbackend.libraries.mockito.service.FooService<com.frontbackend.libraries.mockito.model.Car>'
but since it is just a JUnit class we could suppress this warning with the following annotation, and should not be worried about clean code that much:
@SuppressWarnings("unchecked")
4. Using @Mock
annotation
The second way to mock a class with a generic parameter is to use @Mock
annotation. This approach requires MockitoJUnitRunner
:
package com.frontbackend.libraries.mockito;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import com.frontbackend.libraries.mockito.model.Car;
import com.frontbackend.libraries.mockito.model.Driver;
import com.frontbackend.libraries.mockito.service.FooService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class MockitoMockClassWithGenericParamUsingAnnotationTest {
@Mock
public FooService<Car> mockFoo;
@Test
public void testFoo() {
when(mockFoo.getValue()).thenReturn(new Car(new Driver("Mr Bean")));
Car value = mockFoo.getValue();
assertEquals("Welcome Mr Bean!", value.printWelcome());
}
}
In this example code we used @Mock annotation to create a mock object of FooService
class. There is no obstacle to use a generic parameter for this object.
5. Conclusion
In this article, we present how to mock classes with generic parameters using Mockito.
As usual, code introduced in this article is available in our GitHub repository.
{{ 'Comments (%count%)' | trans {count:count} }}
{{ 'Comments are closed.' | trans }}