Skip to content

RETURNS_SELF breaks methods with generic return type #2686

@mlichtblau

Description

@mlichtblau

I'm trying to use RETURNS_SELF to mock a builder with a generic method:

private static class HttpBuilder {
  private String uri;
  
  public HttpBuilder withUri(String uri) {
    this.uri = uri;
    return this
  }

  ...

  public <T> T request(T result) {
    return result; // Do typed request
  }
}

It is easy enough to mock using:

val builder = mock(HttpBuilder.class, RETURNS_SELF);

However this breaks:

given(builder.request(anyString())).willAnswer(i"Mocked result");

The problem is, that anyString() infers builder.request to have a String return type, which infers given to have a String methodCall parameter.
However, at runtime a ClassCastException is thrown as builder.request(anyString()) returns a HttpBuilder$MockitoMock which cannot be cast to the the String expected by given.
(I think) this is caused by RETURNS_SELF here in the TriesToReturnSelf class. The generic method has the return type Object which is obviously assignable from mockType. This causes mockito to always undesirably return this with methods with generic return types when using RETURNS_SELF.

Is it possible for mockito to check whether the return type of the method is generic? In that case I would suggest a fix to never return this for methods with generic return types.
If you think this would be a good solution, I am happy to contribute a fix.

edit: What do you think of checking whether return type is of type Object.class, which suggests that mockito should probable return the empty value instead of this

edit 2: Added #2687 to demonstrate the issue with a test and solution proposal. Happy to update with any comments

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions