14

We're looking at switching to Spring 3.0 and running into problems with the intersection of Spring 3.0, EasyMock, and Java Generics.

In one place, we're mocking a Spring 3.0 AbstractBeanFactory, specifically this method:

public Class<?> getType(String name) throws NoSuchBeanDefinitionException { ... }

Under earlier versions of Spring, this returns a non-generic and all was well. With the generic, however, we run into trouble with this:

expect(mockBeanFactory.getType(CLASS_NAME)).andReturn(SOME_CLASS);

Because getType returns Class<?>, andReturn requires Class<?> as a parameter, which simply doesn't work properly.

Is there a known workaround to this?

Alan Krueger
  • 4,701
  • 4
  • 35
  • 48

2 Answers2

21

I've run into a problem like this before, with Mockito. I'm not sure why it happens yet. You can cast the expect(..) argument to the non-generic Class type, ala

expect((Class) mockBeanFactory.getType(CLASS_NAME)).andReturn(SOME_CLASS);

Then you'll just have a warning, which you can suppress if you want. Not a very elegant solution; I'm going to spend a few more minutes looking at it.

Ladlestein
  • 6,100
  • 2
  • 37
  • 49
  • 5
    That does the trick. Sadly, I've come to expect inelegant solutions when dealing with Java Generics. – Alan Krueger Jul 15 '10 at 19:50
  • 4
    +1 to both of you. @AlanKrueger - I can't +1 this enough. I spent 20 minutes *just trying to figure out how to search for this problem* :P – Matt Mills Oct 27 '11 at 21:10
  • My guess as to why this happens is that Java can't be sure that the wildcard type that is returned from EasyMock's `expects()` will be the same type as the wildcard type that is returned from `andReturns()`. In the implementation, there is only one wildcard to for the compiler to deal with: the method's return type. The way EasyMock is set up, there needs to be two wildcards: the expected return type and the actual return type. And when there's a wildcard in each type, – Trent Jul 20 '12 at 16:24
3

The easiest thing to avoid any casting and warnings is to use expectLastCall() instead of expect(..) (see my answer to a similar question for details).

So in this case:

mockBeanFactory.getType(CLASS_NAME);
expectLastCall().andReturn(SOME_CLASS);
Community
  • 1
  • 1
sfussenegger
  • 35,575
  • 15
  • 95
  • 119