An add-on to Retrofit for implementing fake services with network behavior simulation.
npx @tessl/cli install tessl/maven-com-squareup-retrofit2--retrofit-mock@3.0.0Retrofit Mock is a Java library that provides mock web server functionality for testing HTTP responses and simulating network behavior with Retrofit. It enables developers to create controllable, deterministic network simulations without requiring actual network connections, making it ideal for unit testing HTTP-based applications.
Package Name: retrofit-mock
Package Type: maven
Language: Java
Installation:
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit-mock</artifactId>
<version>3.0.0</version>
</dependency>Gradle:
implementation 'com.squareup.retrofit2:retrofit-mock:3.0.0'import retrofit2.mock.MockRetrofit;
import retrofit2.mock.NetworkBehavior;
import retrofit2.mock.BehaviorDelegate;
import retrofit2.mock.Calls;import retrofit2.Retrofit;
import retrofit2.mock.MockRetrofit;
import retrofit2.mock.NetworkBehavior;
import retrofit2.mock.BehaviorDelegate;
import retrofit2.mock.Calls;
// Create a Retrofit instance
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://example.com")
.build();
// Create network behavior with simulated delays and failures
NetworkBehavior behavior = NetworkBehavior.create();
behavior.setDelay(1000, TimeUnit.MILLISECONDS);
behavior.setFailurePercent(10); // 10% failure rate
// Create MockRetrofit instance
MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit)
.networkBehavior(behavior)
.build();
// Create a mock service delegate
BehaviorDelegate<MyService> delegate = mockRetrofit.create(MyService.class);
// Create a mock implementation
MyService mockService = delegate.returningResponse("Hello World");The Retrofit Mock library consists of four main components:
Create MockRetrofit instances to coordinate mock behavior with real Retrofit configurations.
public final class MockRetrofit {
public Retrofit retrofit();
public NetworkBehavior networkBehavior();
public Executor backgroundExecutor();
public <T> BehaviorDelegate<T> create(Class<T> service);
}public static final class MockRetrofit.Builder {
public Builder(Retrofit retrofit);
public Builder networkBehavior(NetworkBehavior behavior);
public Builder backgroundExecutor(ExecutorService executor);
public MockRetrofit build();
}Usage Example:
MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit)
.networkBehavior(NetworkBehavior.create())
.backgroundExecutor(Executors.newSingleThreadExecutor())
.build();Configure realistic network conditions including delays, variance, and failure rates.
public final class NetworkBehavior {
public static NetworkBehavior create();
public static NetworkBehavior create(Random random);
// Delay configuration
public void setDelay(long amount, TimeUnit unit);
public long delay(TimeUnit unit);
// Variance configuration
public void setVariancePercent(int variancePercent);
public int variancePercent();
// Failure configuration
public void setFailurePercent(int failurePercent);
public int failurePercent();
public void setFailureException(Throwable exception);
public Throwable failureException();
// Error response configuration
public int errorPercent();
public void setErrorPercent(int errorPercent);
public void setErrorFactory(Callable<Response<?>> errorFactory);
public Response<?> createErrorResponse();
// Behavior calculation
public boolean calculateIsFailure();
public boolean calculateIsError();
public long calculateDelay(TimeUnit unit);
}Default Configuration:
Usage Example:
NetworkBehavior behavior = NetworkBehavior.create();
behavior.setDelay(500, TimeUnit.MILLISECONDS);
behavior.setVariancePercent(20);
behavior.setFailurePercent(5);
behavior.setErrorPercent(10);Create mock implementations of Retrofit service interfaces with applied network behavior.
public final class BehaviorDelegate<T> {
public T returningResponse(@Nullable Object response);
public <R> T returning(Call<R> call);
}Usage Example:
// Define your service interface
interface ApiService {
@GET("/users")
Call<List<User>> getUsers();
}
// Create delegate and mock implementation
BehaviorDelegate<ApiService> delegate = mockRetrofit.create(ApiService.class);
// Mock with simple response
ApiService mockService = delegate.returningResponse(Arrays.asList(
new User("John", "john@example.com"),
new User("Jane", "jane@example.com")
));
// Mock with custom Call behavior
ApiService mockService2 = delegate.returning(
Calls.response(Response.success(userList))
);Create Call instances that immediately respond with success or failure, useful for testing specific scenarios.
public final class Calls {
public static <T> Call<T> defer(Callable<Call<T>> callable);
public static <T> Call<T> response(@Nullable T successValue);
public static <T> Call<T> response(Response<T> response);
public static <T> Call<T> failure(IOException failure);
public static <T> Call<T> failure(Throwable failure);
}Usage Examples:
// Immediate success response
Call<String> successCall = Calls.response("Success!");
// Immediate failure
Call<String> failureCall = Calls.failure(new IOException("Network error"));
// Custom response with metadata
Response<String> customResponse = Response.success("Data",
new okhttp3.ResponseBody.create(null, ""));
Call<String> customCall = Calls.response(customResponse);
// Deferred call that computes response when executed
Call<String> deferredCall = Calls.defer(() -> {
if (shouldSucceed()) {
return Calls.response("Success");
} else {
return Calls.failure(new IOException("Deferred failure"));
}
});// NetworkBehavior uses these standard Java types
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Callable;
import java.util.Random;
// Retrofit and OkHttp types used throughout
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executor;// Default exception thrown by network failures
final class MockRetrofitIOException extends IOException {
MockRetrofitIOException();
}The library handles errors through several mechanisms:
Network Failures: Configured via setFailurePercent() and setFailureException()
HTTP Errors: Configured via setErrorPercent() and setErrorFactory()
Immediate Failures: Created via Calls.failure()
Error Configuration Example:
NetworkBehavior behavior = NetworkBehavior.create();
// Custom failure behavior
behavior.setFailurePercent(15);
IOException customException = new IOException("Custom network failure");
customException.setStackTrace(new StackTraceElement[0]); // Remove misleading stack trace
behavior.setFailureException(customException);
// Custom error responses
behavior.setErrorPercent(20);
behavior.setErrorFactory(() ->
Response.error(404, ResponseBody.create(null, "Not Found")));The library fully supports Retrofit's Kotlin suspend functions:
interface ApiService {
@GET("/users")
suspend fun getUsers(): List<User>
@GET("/user/{id}")
suspend fun getUser(@Path("id") id: String): Response<User>
}
// Mock implementation works seamlessly with suspend functions
val mockService = delegate.returningResponse(listOf(User("test")))
val users = mockService.getUsers() // Suspend function callControl background execution with custom ExecutorService:
ExecutorService customExecutor = Executors.newFixedThreadPool(2);
MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit)
.backgroundExecutor(customExecutor)
.build();Common testing patterns with Retrofit Mock:
@Test
public void testNetworkFailure() {
NetworkBehavior behavior = NetworkBehavior.create();
behavior.setFailurePercent(100); // Force failure
MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit)
.networkBehavior(behavior)
.build();
ApiService service = mockRetrofit.create(ApiService.class)
.returningResponse("test");
// This call will fail due to 100% failure rate
Call<String> call = service.getData();
// ... test failure handling
}
@Test
public void testSlowNetwork() {
NetworkBehavior behavior = NetworkBehavior.create();
behavior.setDelay(5, TimeUnit.SECONDS);
behavior.setVariancePercent(50); // ±50% variance
// ... test timeout handling and slow network scenarios
}