简体   繁体   中英

Mocking methods that return generics and primitives with Mockito

I'm trying to mock a class using Mockito 1.9.5 but I'm having a lot of trouble getting it to work.

public class Property<T> {
    private T value;
    public T get() { return this.value; }
    public void set(T value) { this.value = value; }
}

public class Model {
    private final Property<Integer> count = new Property<Integer>();
    public Property<Integer> count() { return this.count; }
}

public class View {
    public View(Model model) {
        Integer count = model.count().get();
    }
}

I wrote my test boilerplate:

Model model = mock(Model.class, Mockito.RETURNS_MOCKS);
View view = new View(model);

... and got a long ClassCastException :

Exception in thread "main" java.lang.ClassCastException: org.mockito.internal.creation.jmock.ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug$$Enhancer

ByMockitoWithCGLIB$$cb6ca60b cannot be cast to java.lang.Integer

I know that Mockito can't mock final classes or primitives, but I'm at a loss for what I need to do to make this work.

The generic type of your class Property<Integer> is erased during compilation. Mockito can only pick up the runtime type of your erased method. To Mockito, your class looks something like this:

public class Property {
  private Object value;
  public Object get() { return this.value; }
  public void set(Object value) { this.value = value; }
}

When you mock this class, your call to model.count().get() is implicitly cast to Integer where this instruction is added by javac due to your generic information. However, Mockito only returns a mock of an Object type after it observed the types above, thus the exception. Instead of

mock(Model.class, Mockito.RETURNS_MOCKS);

define the return value explicitly

mock(Model.class, Mockito.RETURNS_DEEP_STUBS); // intermediate mocks
when(model.count().get()).thenReturn(0);

The Integer type is final and cannot be mocked which is why you need to return a dummy value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM