EasyMock: How do I create a mock of a genericized class without a warning?

27,398

Solution 1

AFAIK, you can't avoid the unchecked warning when a class name literal is involved, and the SuppressWarnings annotation is the only way to handle this.

Note that it is good form to narrow the scope of the SuppressWarnings annotation as much as possible. You can apply this annotation to a single local variable assignment:

public void testSomething() {

    @SuppressWarnings("unchecked")
    Foo<Integer> foo = EasyMock.createMock(Foo.class);

    // Rest of test method may still expose other warnings
}

or use a helper method:

@SuppressWarnings("unchecked")
private static <T> Foo<T> createFooMock() {
    return (Foo<T>)EasyMock.createMock(Foo.class);
}

public void testSomething() {
    Foo<String> foo = createFooMock();

    // Rest of test method may still expose other warnings
}

Solution 2

I worked around this problem by introducing a subclass, e.g.

private abstract class MySpecialString implements MySpecial<String>{};

Then create a mock of that abstract class:

MySpecial<String> myMock = createControl().createMock(MySpecialString.class);

Solution 3

The two obvious routes are to suppress the warning or mock a subclass.

private static class SomeClass_Integer extends SomeClass<Integer>();
private SomeClass<Integer> someClass;
...
    someClass = EasyMock.createMock(SomeClass_Integer.class);

(Disclaimer: Not even attempted to compile this code, nor have I used EasyMock.)

Solution 4

You can annotate the test method with @SuppressWarnings("unchecked"). I agree this is some what of a hack but in my opinion it's acceptable on test code.

@Test
@SuppressWarnings("unchecked")
public void someTest() {
    SomeClass<Integer> someClass = EasyMock.createMock(SomeClass.class);
}

Solution 5

I know this goes against the question, but why not create a List rather than a Mock List?

It's less code and easier to work with, for instance if you want to add items to the list.

MyItem myItem = createMock(myItem.class);
List<MyItem> myItemList = new ArrayList<MyItem>();
myItemList.add(myItem);

Instead of

MyItem myItem = createMock(myItem.class);
@SuppressWarnings("unchecked")
List<MyItem> myItemList = createMock(ArrayList.class);
expect(myItemList.get(0)).andReturn(myItem);
replay(myItemList);
Share:
27,398

Related videos on Youtube

Sabby
Author by

Sabby

Updated on October 11, 2020

Comments

  • Sabby
    Sabby over 3 years

    The code

    private SomeClass<Integer> someClass;
    someClass = EasyMock.createMock(SomeClass.class);
    

    gives me a warning "Type safety: The expression of type SomeClass needs unchecked conversion to conform to SomeClass<Integer>".

  • Brian Matthews
    Brian Matthews over 15 years
    The syntax should probably be: private static interface SomeClass_Integer extends SomeClass<Integer> {} I have the same problem and this is the work around I use so the approach will work. But I hope somebody has the answer we are looking for
  • Sabby
    Sabby over 15 years
    yeah, but that leaves me feeling cheap
  • SamBeran
    SamBeran over 15 years
    If you go this route (hopefully there is a better way), much better to put the @SuppressWarnings on the variable assignment rather than the whole method.
  • Andreas
    Andreas over 11 years
    Additionally, don't forget to use the org.easymock.classextension.EasyMock version of EasyMock to create your mocks when using the abstract class.
  • AndrewF
    AndrewF almost 7 years
    As of EasyMock 3.0 (May 2010), the classes in org.easymock.classextension are deprecated and are simple proxies to the same-named classes in org.easymock. It is recommended to remove ".classextension" from your imports and stop compiling with the classextension library.