Mockito ClassCastException - макет не может быть запущен

У меня есть метод в классе AppleProcessor, который я бы хотел проверить:

public void process(Fruit fruit) {
    if(fruit.getType() == Fruit.APPLE) {
        fruitBasket.add(((AppleFruit) fruit).getApple());
    }
    else {
        // do something else
    }
}

Обратите внимание, что Fruit является интерфейсом с методом getType(), который AppleFruit реализует, а также имеет метод getApple().

Мой тест выглядит следующим образом:

@Mock
FruitBasket fruitBasket;

@Mock
Fruit fruit;

@Mock
AppleFruit apple;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void testAnAppleIsProcessed() {
    AppleProcessor appleProcessor = new AppleProcessoer();
    when(fruit.getType()).thenReturn(Fruit.APPLE);
    when(((AppleFruit) fruit).getApple()).thenReturn(apple);

    appleProcessor.process(fruit);

    verify(fruitBasket).add(isA(Apple.class));
}

Однако я получаю следующую ошибку:

java.lang.ClassCastException: package.fruit.Fruit$$EnhancerByMockitoWithCGLIB$$b8254f54 cannot be cast to package.fruit.AppleFruit

который исходит из этой строки в тесте

when(((AppleFruit) fruit).getApple()).thenReturn(apple);

Кто-нибудь знает, как разрешить это, чтобы я мог проверить свой код?

Ответ 1

Когда вы говорите

@Mock
Fruit fruit;

Вы скажете Mockito: переменная fruit должна быть экземпляром fruit. Mockito будет динамически создавать класс, который реализует fruit (этот класс Fruit$$EnhancerByMockitoWithCGLIB$$b8254f54) и создает экземпляр этого класса. Нет причин для этого класса быть экземпляром AppleFruit, так как вы не сказали Mockito, что объект должен быть типа AppleFruit.

Объявите его как AppleFruit, и он будет иметь тип AppleFruit.

Ответ 2

Ваш mock-объект улучшен с помощью Mockito, и он не такой же, как ваш класс, поэтому вы не можете набирать текст.

Ответ 3

Вы можете указать mockito возвращать объект типа подкласса для метода, который возвращает объект суперкласса. Тогда вам не нужно будет указывать мокито, чтобы он сотворил объект.