New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Support For Generics Inference In Mockito mock() and spy() method #1531
Comments
@ankurpathak if you will check what EasyMock did, they make the BaseGenericClass<Integer> mock = EasyMock.createMock(BaseGenericClass.class); but you can also do BaseGenericClass<Integer> mock = EasyMock.createMock(Set.class); very strange, ha?! I'll try to give a better fix... |
@brachi-wernick This is already done for mockito/src/main/java/org/mockito/ArgumentCaptor.java Lines 148 to 150 in 41c5606
It doesn't make it completely typed as you can accidentally give it |
Hi, While it is not exactly what you are looking for, please note that at this time, if the types to mock are declared as fields in a test, then the compiler will propagate types. import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.util.Map;
import static java.lang.Long.MAX_VALUE;
import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
public class GenericFieldTest {
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Mock
private Map<Number, Iterable<String>> typeToMock;
@Test
public void should_propagate_generics() {
given(typeToMock.get(MAX_VALUE)).willReturn(singleton("max"));
given(typeToMock.put(MAX_VALUE, singleton("max"))).willReturn(singleton("maximum"));
assertThat(typeToMock.put(MAX_VALUE, singleton("max"))).isEqualTo(singleton("maximum"));
assertThat(typeToMock.get(MAX_VALUE)).isEqualTo(singleton("max"));
}
} Also we discussed about the trick that easy mock used, and we're not really sold to it because of the drawbacks mentioned above. Some other libraries employs other approaches that are safer but require a stronger commitment to the codebase. |
@SerialVelocity why does ArgumentCaptor have two type parameters? That allows something like the following doesn't it: ArgumentCaptor<Object> ac = ArgumentCaptor.forClass(Integer.class); which isn't semantically accurate. That's saying you're trying to declare an If you try something similar with Lists it wouldn't compile: // Won't compile
List<Object> ol = new ArrayList<Integer>(); |
@thandy1212 I'm just stating what already exists in Mockito, not something new. I assume it was done because you don't really care about what subclass it is implementing. If you pass
It's the same as if you had:
The only thing you have restricted is you cannot call |
As of this writing, there are 292 upvotes for the related Stack Overflow question around mocking with generic parameters. This indicates to me that there is definitely an interest in having a clean solution to this problem. |
Given that |
A problem I've seen with |
Since you are dynamically creating the mock, it means you are creating it on runtime. Because of type erasure, at runtime these generics types are not checked. Therefore, I don't think it is possible to create a type-safe API with |
@TimvdLippe Agreed, regarding using Examples:
The code could then look something like: List<String> mock = mock(new TypeReference<List<String>>(){}); |
no fix from but see mockito/mockito#1531
I don't like ignoring warnings and I hate adding warning-ignore comments in code (they don't belong there). Please help! |
This is an issue well known by the Mockito community, but prone to not be fixed: mockito/mockito#1531 Generics allow to ensure type-safety at compile time instead of runtime. However, here it is used mainly to auto-cast the created object, thus avoiding this burden on the developer. Indeed, it is in a context where type safety is usually not a requirement, since the use of this method is often the most trivial we can have: provide a class and expect a very instance of this class in return. This commit thus creates a less constrained mock method which builds on Mockito's one, but without the constraint inducing this warning.
This is an issue well known by the Mockito community, but prone to not be fixed: mockito/mockito#1531 Generics allow to ensure type-safety at compile time instead of runtime. However, here it is used mainly to auto-cast the created object, thus avoiding this burden on the developer. Indeed, it is in a context where type safety is usually not a requirement, since the use of this method is often the most trivial we can have: provide a class and expect a very instance of this class in return. This commit thus creates a less constrained mock method which builds on Mockito's one, but without the constraint inducing this warning.
Hi, Have you planned to resolve this issue? |
EasyMock with its version 4 added support for Generics to get rid of Annoying Unchecked Warning while
mocking types with Generics Involved. So we expect the same with Mockito, in its mock() and spy() to add
support for generics type inference, so that the developers have not to deal with annoying Uncheked
warning in Test and annotate tests with SuppressWarnings({"unchecked"}). For a motivation for same we
can have a look at emptyList(), empthMap() and emptySet() method of Collections class in JDK.
And also have a look at the way it is done in EasyMock 4.0 in this class:
https://github.com/easymock/easymock/blob/master/core/src/main/java/org/easymock/EasyMock.java
The text was updated successfully, but these errors were encountered: