我在班级AppleProcessor
中有一个方法,我想测试一下:
public void process(Fruit fruit) {
if(fruit.getType() == Fruit.APPLE) {
fruitBasket.add(((AppleFruit) fruit).getApple());
}
else {
// do something else
}
}
请注意,Fruit是AppleFruit实现的方法getType()
的接口,并且还有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);
有人知道如何解决这个问题,以便我可以测试我的代码吗?
答案 0 :(得分:28)
当你说
时@Mock
Fruit fruit;
你告诉Mockito:fruit
变量应该是Fruit
的一个实例。 Mockito将动态创建一个实现Fruit
的类(此类为Fruit$$EnhancerByMockitoWithCGLIB$$b8254f54
),并创建此类的实例。这个课程没有理由成为AppleFruit
的实例,因为你没有告诉Mockito该对象必须是AppleFruit类型。
将其声明为AppleFruit
,它的类型为AppleFruit
。
答案 1 :(得分:1)
Mockito 可以处理在模拟时间(赋值)时已经投射的模拟对象。但是,它不会在代码执行期间自行转换模拟对象。
换句话说(或者更好的是代码):
Fruit fruit = Mockito.mock(Applefruit.class);
按照 JB Nizet 说的去做,你会没事的。我遇到了类似的问题,他的解决方案奏效了。
对于这个问题,应该是:
@Mock
FruitBasket fruitBasket;
@Mock
AppleFruit fruit; // chaged here
@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));
}
这就是所需要的。
答案 2 :(得分:0)
您的模拟对象由Mockito增强,并且与您的类不同,因此您无法输入强制转换。
答案 3 :(得分:0)
对于返回超类对象的方法,您可以指示Mockito返回子类类型的对象。然后,您将不需要告诉Mockito投射对象。
答案 4 :(得分:0)
对于搜索此内容的任何人,请包括:
@Mock(extraInterfaces = {AppleFruit.class})
Fruit fruit;
这将为模拟添加一个额外的接口,并且转换不会引发任何异常。