8

I'm using mockito to write some tests, and I'm using the following bit of code:

ArgumentCaptor<LinkedList> captor = ArgumentCaptor.forClass(LinkedList.class); 

This compiles and runs just fine, except for the warning that "captor" is raw type and I should replace it with something like:

ArgumentCaptor<LinkedList<String>> captor = ArgumentCaptor.forClass(LinkedList<String>.class);

The problem is that LinkedList<String>.class doesn't exist, so the right side of the assignment will never compile.

Assuming that suppressing the warning is inelegant, is there an elegant solution? If not, why does the compile warn me about something I can't really fix?

jwepurchase
  • 733
  • 6
  • 22
  • did you try `LinkedList>`? – jtahlborn Dec 21 '14 at 05:16
  • 2
    I don't think you're going to get an answer you'll like. Generics already increased the complexity of the language by a staggering degree (wildcards, <>, recursive bounds that nobody understands, generic methods, new meanings of `extends` and `super` etc etc), so be thankful it wasn't even worse. Making this compile without a warning would have required making the language even more complicated (specifically `LinkedList.class` would have to have been made legal code), so in a way you should be thankful it doesn't work. I think you just have to suppress the warning and forget about it. – Paul Boddington Dec 21 '14 at 05:28
  • 2
    @pbabcdefp There's actually a mechanism in Mockito specifically designed to get around issues with generics. You just annotate your declarations and then ask Mockito to create everything for you. – azurefrog Dec 21 '14 at 05:33
  • @azurefrog Thanks. I've never even heard of Mockito. Can it do anything about the irritating "generic array creation" warning you get when you try to create a `List>` using `Arrays.asList`? – Paul Boddington Dec 21 '14 at 05:35
  • possible duplicate of [Mockito isA(Class clazz) How to resolve type safety?](http://stackoverflow.com/questions/12012249/mockito-isaclasst-clazz-how-to-resolve-type-safety) – Joe Dec 21 '14 at 05:35
  • @Joe: It has something to do with Mockito, but I don't see that as a duplicate. – Makoto Dec 21 '14 at 05:36
  • 1
    @Joe I don't think the `TypeToken` approach is appropriate here, since the annotation approach is so much cleaner. The Captor API docs even call this specific situation out: "One of the advantages of using @Captor annotation is that you can avoid warnings related capturing complex generic types." – azurefrog Dec 21 '14 at 05:37
  • @azurefrog: I wasn't really asking a mockito question; it was just an example of the latest place this annoyance has come up for me. The annotation does get around the problem elegantly in this case, but does this mean that it is best to avoid using the class literal as a method parameter? – jwepurchase Dec 21 '14 at 12:54
  • @pbabcdefp - I like the answer I won't like. If the alternative is a horrendous, over-complicated mess, I can live with that. – jwepurchase Dec 21 '14 at 13:00

1 Answers1

7

There is a @Captor annotation in Mockito which is designed to allow you to avoid warnings like this.

Using it, you don't need to manually new up your ArgumentCaptor. You can just declare it with the annotation and then call MockitoAnnotations.initMocks(this); to "automatically" create your captor.

instead of this:

ArgumentCaptor<LinkedList> captor = ArgumentCaptor.forClass(LinkedList.class); 

do this:

@Captor
ArgumentCaptor<LinkedList<String>> captor;

@Before
public void init() {
   // initialize fields annotated with Mockito annotations
   MockitoAnnotations.initMocks(this);  
}
azurefrog
  • 10,785
  • 7
  • 42
  • 56
  • 1
    You should now use `@RunWith(MockitoJUnitRunner.class)` or the new `MockitoJunitRule` instead of `MockitoAnnoyions.initMocks(this)`, they are safer. Not to mention the naming is better too, it's not only about mocks. – bric3 Dec 21 '14 at 10:13
  • Thanks for the mockito tip. – jwepurchase Dec 21 '14 at 12:44
  • I'm going to accept this answer because, while I wasn't really asking a Mockito question, it put me on to a way of solving it. (I edited the answer to add links to that solution). But what a solution! It's unlikely that if I were writing code I'd go to all that trouble to rid myself of a compiler warning. – jwepurchase Dec 21 '14 at 14:13