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 возвращать объект типа подкласса для метода, который возвращает объект суперкласса. Тогда вам не нужно будет указывать мокито, чтобы он сотворил объект.