Question

Return a Method Argument with Mockito in Java

javamockito

Question

Given the following Java method signature:

public String myFunction(String abc);

Can Mockito configure a mock so that myFunction returns the same String value that was passed as its abc argument?

Short Answer

You will learn how to make a Mockito stub return one of the arguments supplied to a mocked method. This is useful when a dependency behaves like an identity function, echo service, converter, or pass-through layer.

Concept

Mockito stubbing usually returns a fixed value:

when(mock.myFunction(anyString())).thenReturn("fixed value");

Sometimes the result must depend on the call's input instead. For example, if the mock receives "hello", you want it to return "hello"; if it receives "world", you want it to return "world".

Mockito supports dynamic return values through an Answer. An answer runs when the mocked method is called and can inspect its arguments.

For the common case of returning an argument unchanged, Mockito provides the concise helper AdditionalAnswers.returnsFirstArg(). Since myFunction has one argument, its first argument is the value of abc.

This matters because tests should model the behavior that the code under test expects. A fixed return value may hide bugs when your production code needs to handle different input values.

Mental Model

Think of a mocked method as a receptionist.

  • thenReturn("OK") tells the receptionist: “Always give every caller the same prewritten reply.”
  • returnsFirstArg() tells the receptionist: “Repeat the first thing each caller says.”
  • thenAnswer(...) tells the receptionist: “Read what the caller said, then decide how to respond.”

Returning an argument is the “repeat what the caller said” behavior.

Take Quiz

Syntax and Examples

Use AdditionalAnswers.returnsFirstArg() when the desired return value is the first parameter.

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import static org.mockito.AdditionalAnswers.returnsFirstArg;

MyService service = mock(MyService.class);

when(service.myFunction(anyString()))
    .thenAnswer(returnsFirstArg());

assertEquals("hello", service.myFunction("hello"));
assertEquals("Mockito", service.myFunction("Mockito"));

anyString() matches any non-null String argument. returnsFirstArg() retrieves argument index 0 from the current invocation and returns it.

For a general-purpose solution, write an Answer lambda:

when(service.myFunction(anyString()))
    .thenAnswer(invocation -> invocation.getArgument(0, String.class));

The getArgument(0, String.class) call means “get the first argument and treat it as a String.”

If a method has multiple parameters and you need the second one, use returnsSecondArg() or argument index 1:

when(service.combine(anyString(), anyString()))
    .thenAnswer(invocation -> invocation.getArgument(1, String.class));

Step by Step Execution

Consider this test setup:

when(service.myFunction(anyString()))
    .thenAnswer(returnsFirstArg());

String result = service.myFunction("report.csv");

Execution happens as follows:

  1. Mockito receives the call service.myFunction("report.csv").
  2. The matcher anyString() matches the argument because "report.csv" is a String.
  3. Mockito finds the configured stub.
  4. returnsFirstArg() reads argument 0, which is "report.csv".
  5. Mockito returns "report.csv".
  6. result contains "report.csv".

The mock does not call real production code. It returns the value entirely because of the test configuration.

Real World Use Cases

Returning an input argument is useful when a dependency's exact internal behavior is not relevant to the test.

  • File or object storage adapters: a fake upload method may return the generated key passed into it.
  • Message pipelines: a mock transformer may pass a message through unchanged so you can test routing logic.
  • Repository save operations: a mock can return the entity supplied to save, especially when testing service-layer flow.
  • Normalization or mapping boundaries: while testing later steps in a pipeline, a mapper mock can temporarily behave as an identity mapping.
  • Callback-style APIs: a mocked handler can return the request, command, or payload it received.

Example with an entity:

when(repository.save(any(User.class)))
    .thenAnswer(invocation -> invocation.getArgument(0, User.class));

This lets a service test proceed with the same User object it attempted to save.

Take Quiz

Real Codebase Usage

In real test suites, use argument-returning stubs only when that behavior is meaningful to the test.

Repository save pattern

A service often creates or updates an object and passes it to a repository:

when(userRepository.save(any(User.class)))
    .thenAnswer(invocation -> invocation.getArgument(0, User.class));

This is practical when the service needs the saved object but the database-generated ID is not part of the scenario.

Validation and guard clauses

First test that invalid input stops before the dependency is called:

assertThrows(IllegalArgumentException.class,
    () -> service.createUser(""));

verifyNoInteractions(userRepository);

Then use a dynamic answer for valid input tests.

Enriching an input instead of simply returning it

When a repository should assign an ID, use thenAnswer rather than returnsFirstArg():

when(userRepository.save(any(User.class))).thenAnswer(invocation -> {
    User user = invocation.getArgument(0, User.class);
    user.setId(100L);
    return user;
});

This keeps the test behavior explicit: the dependency returns the submitted user after adding an ID.

Prefer simple, intention-revealing stubs

Use returnsFirstArg() when it accurately describes the dependency behavior. Use a lambda only when you need transformation, conditions, generated values, or inspection of several arguments.

Common Mistakes

Returning a fixed value accidentally

This compiles, but it returns "abc" for every call:

when(service.myFunction(anyString())).thenReturn("abc");

Use returnsFirstArg() or thenAnswer(...) when the output must vary with input.

Calling the mock while configuring a spy

With a pure mock, when(mock.method()) is normally fine. With a spy, the real method may run during stubbing:

// Risky for spies: may execute the real method now
when(spy.myFunction(anyString())).thenAnswer(returnsFirstArg());

For spies, prefer the doAnswer style:

doAnswer(returnsFirstArg())
    .when(spy)
    .myFunction(anyString());

Mixing matchers and literal values

When one argument uses a matcher, Mockito generally requires matchers for all arguments in that invocation:

// Incorrect
when(service.combine(anyString(), "suffix"));

Use eq for the literal:

when(service.combine(anyString(), eq("suffix")))
    .thenAnswer(invocation -> invocation.getArgument(0, String.class));

Forgetting that anyString() does not match null

anyString() is intended for non-null strings. If the method may receive null, use a matcher that permits it:

when(service.myFunction(nullable(String.class)))
    .thenAnswer(returnsFirstArg());

Using the wrong argument index

Argument indexes start at 0:

invocation.getArgument(0); // first argument
invocation.getArgument(1); // second argument

Trying to read index 1 from myFunction(String abc) is invalid because the method has only one argument.

Comparisons

ApproachBest forBehavior
thenReturn(value)A constant resultAlways returns the same value
thenAnswer(returnsFirstArg())Returning the first input unchangedReturns argument at index 0
thenAnswer(returnsSecondArg())Methods with two or more inputsReturns argument at index 1
thenAnswer(invocation -> ...)Custom dynamic behaviorCan inspect arguments and compute a result
thenCallRealMethod()Partial behavior on a mockInvokes the actual implementation

For the original one-argument method, these two are equivalent in intent:

when(service.myFunction(anyString())).thenAnswer(returnsFirstArg());

when(service.myFunction(anyString()))
    .thenAnswer(invocation -> invocation.getArgument(0, String.class));

Prefer returnsFirstArg() when no extra logic is needed. It is shorter and makes the test's intent clear.

Take Quiz

Cheat Sheet

import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

when(mock.myFunction(anyString()))
    .thenAnswer(returnsFirstArg());

Custom equivalent:

when(mock.myFunction(anyString()))
    .thenAnswer(invocation -> invocation.getArgument(0, String.class));

Useful helpers:

returnsFirstArg();  // argument index 0
returnsSecondArg(); // argument index 1
returnsLastArg();   // final argument

Rules:

  • Argument indexes are zero-based.
  • Use thenReturn for fixed values.
  • Use thenAnswer when output depends on the invocation.
  • anyString() is for non-null strings; use nullable(String.class) if null is allowed.
  • For spies, doAnswer(...).when(spy).method(...) avoids invoking the real method during setup.

FAQ

How do I return the input argument in Mockito?

Use thenAnswer(returnsFirstArg()) after stubbing the method with when(...).

when(mock.myFunction(anyString())).thenAnswer(returnsFirstArg());

What does returnsFirstArg() return?

It returns the first argument supplied in the current mocked method call. For a method with one parameter, it returns that parameter.

Can I return the second argument instead?

Yes. Use returnsSecondArg() or a custom answer:

.thenAnswer(invocation -> invocation.getArgument(1))

Is thenAnswer better than thenReturn?

Neither is always better. Use thenReturn for a fixed result and thenAnswer when the result depends on arguments or other call details.

Can I use returnsFirstArg() with object parameters?

Yes. It works with compatible reference types, such as User, Order, or String.

Does anyString() match null in Mockito?

No. Use nullable(String.class) if the stub must match both strings and null.

Should I use this with a Mockito spy?

You can, but use doAnswer(...).when(spy) to avoid calling the real method while stubbing.

Take Quiz

Mini Project

Description

Create a small service that saves a Note through a repository. In the unit test, configure the mocked repository to return the exact Note instance it receives. This models a simple save operation without requiring a database.

Goal

Write a Mockito test where NoteRepository.save returns the note passed to it and verify the service returns that saved note.

Requirements

Define a Note class with a text field. Define a NoteRepository interface with a save(Note note) method. Create a NoteService that creates a note and sends it to the repository. Mock the repository in a JUnit test. Configure save to return its first argument and verify the saved text.

Take Quiz

Keep learning

Related questions

View more