title: deep within JUnit Parameterized test runner: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.List
body: <p>I'm attempting to build my first parameterized test using JUnit's ParameterizedTestRunner.  I am getting a weird ClassCastException deep in the bowels of JUnit which I cannot figure out.</p>
  
  <p>Here's what's weird about this: the traceback in Intellij <em>never seems to touch my code.</em></p>
  
  <p>My base class is called MultiLocaleParserTest, and my child class is ExpectNoAltTagsInSellerNamesTest.  Amazon scraping, rejoice!</p>
  
  <pre><code>/**
   * This is the base class for "multi-locale" tests.  Its children are intended
   * to be used with the JUnit Parameterized Test Runner.
   *
   * Currently, contains only boilerplate of use to child classes.
   *
   * @see &lt;a href="https://github.com/junit-team/junit/wiki/Parameterized-tests"&gt;JUnit Parameterized Test Runner docs&lt;/a&gt;
   */
  public abstract class MultiLocaleParserTest extends BaseParserTest {
  
      private static ArrayList&lt;ArrayList&gt; fixtureList;
      private static ArrayList&lt;ArrayList&gt; expectedList;
  
      /**
       * Builds and returns an array that looks like this:
       *
       *  { { String amazonLocale, ArrayList fixtureData, ArrayList expectedData },
       *    { ... },
       *  }
       *
       * TODO: A possible (probable) refactor involves switching the "fixture" and
       *      "expected" data structures to Maps of some type, because it's more reader-
       *      friendly to see e.g. fixture.get("seller_name") than fixture.get(2).
       *
       * @param fixtureList An ArrayList of fixture data for the test the programmer is setting up.
       * @param expectedList An ArrayList of expected results for the test the programmer is setting up.
       * @return A data structure for use with parameterized tests as in class ExpectNoAltTagsInSellerNames.
       */
      protected static Object[] buildLocaleTestDataArray(ArrayList&lt;ArrayList&gt; fixtureList,
                                                         ArrayList&lt;ArrayList&gt; expectedList) throws Exception {
          MultiLocaleParserTest.fixtureList = fixtureList;
          MultiLocaleParserTest.expectedList = expectedList;
          if (fixtureList.size() != expectedList.size()) {
              throw new Exception("Need as many 'expected' entries as 'fixture' entries.");
          }
  
          int c = 0;
          ArrayList&lt;Object[]&gt; testParamData = new ArrayList&lt;&gt;();
          Iterator fixtureIterator = fixtureList.iterator();
          Iterator expectedIterator = expectedList.iterator();
          while (fixtureIterator.hasNext()) {
              ArrayList myFixtureList = (ArrayList)fixtureIterator.next();
              ArrayList myExpectedList = (ArrayList)expectedIterator.next();
  
              String fLocale = (String)myFixtureList.remove(0);
              String eLocale = (String)myExpectedList.remove(0);
  
              if (!fLocale.equals(eLocale)) {
                  throw new Exception("List params to this method must be in the same order.");
              }
  
              ArrayList&lt;Object&gt; testParamList = new ArrayList&lt;&gt;();
              testParamList.add(fLocale);
              testParamList.add(myFixtureList);
              testParamList.add(myExpectedList);
  
              testParamData.add(testParamList.toArray());
              c++;
          }
  
          return testParamData.toArray();
      }
  
      public void smokeTest() throws Exception {
          // @todo derp
      }
  }
  </code></pre>
  
  <p>And the child class, which attempts to actually use the base class. Sorry for all this, it's a mix of my not having touched Java in 6 years and having a Python mindset, and our existing codebase.</p>
  
  <pre><code>/**
   * Regression test vs MT-786 (alt="foo visible in MPS seller name fields)
   *
   * This multi-locale test checks that the string "alt=" does not appear in any
   * seller names which are images, rather than text.
   *
   * This is the proof-of-concept use of JUnit Parameterized tests for multiple
   * Amazon locales.
   *
   * @see MultiLocaleParserTest
   * @see &lt;a href="https://github.com/junit-team/junit/wiki/Parameterized-tests"&gt;JUnit Parameterized Test Runner docs&lt;/a&gt;
   */
  @RunWith(Parameterized.class)
  public class ExpectNoAltTagsInSellerNamesTest extends MultiLocaleParserTest {
  
      /**
       * Params that are filled for each localized test by the JUnit parameterized
       * test runner.  These go in order? or type/signature? based on the return
       * signature of data().
       */
      private String locale;
      private ArrayList fixtureData;
      private ArrayList expectedData;
  
      /**
       * Here is where you, the programmer, set up fixture data and expected results data
       * for each Amazon locale.  You then feed it to MultiLocaleParserTest#buildLocaleTestData
       * to transform it into a data structure for easy use by your actual test code.
       *
       * You must provide both fixture data and expected results for each test's Amazon locale
       * as an ArrayList with the Amazon locale as a String at element 0.
       *
       * Create an ArrayList of these locale-specific ArrayLists, as below, and feed it to
       * MultiLocalParserTest#buildLocaleTestDataArray() for your return value.
       *
       * The JUnit Parameterized Test Runner will then fill the private variables
       * #locale, #fixtureData, and #expectedData with the contents of each array
       * for every locale you define.
       *
       * NOTICE: JUnit 4.11+ should support an argument to the @Parameterized.Parameters()
       * annotiation which makes *which* test blew up when a particular test blows up more
       * understandable.  I was unable to get it to work, possibly due to old versions of
       * JUnit and/or Hamcrest Core.  The thing to paste in the parens is this:
       *
       *   name = "{index}: " + "expectProperHandlingOfImageSellerNames({0}) = {1}"
       *
       * cf. https://github.com/junit-team/junit/wiki/Parameterized-tests#identify-individual-test-cases
       * cf. http://youtrack.jetbrains.com/issue/IDEA-109891#comment=27-560090
       *
       * @return The value is described by MultiLocaleParserTest#buildLocaleTestDataArray()
       * @see MultiLocaleParserTest#buildLocaleTestDataArray(java.util.ArrayList, java.util.ArrayList)
       */
      @Parameterized.Parameters()
      public static Object[] data() throws Exception {
          ArrayList&lt;ArrayList&gt; fixtureList = new ArrayList&lt;&gt;();
  
          fixtureList.add(new ArrayList(Arrays.asList("UK", "/20130909-B0068ZAPB0-New--MST781.html")));
          fixtureList.add(new ArrayList(Arrays.asList("DE", "/20130909-B004LR5PRQ-New--MST781.html")));
          fixtureList.add(new ArrayList(Arrays.asList("FR", "/20130909-B001VL82J8-New--MST781.html")));
  
          ArrayList&lt;ArrayList&gt; expectedList = new ArrayList&lt;&gt;();
          expectedList.add(new ArrayList(Arrays.asList("UK", 10)));
          expectedList.add(new ArrayList(Arrays.asList("DE", 10)));
          expectedList.add(new ArrayList(Arrays.asList("FR", 10)));
  
          return buildLocaleTestDataArray(fixtureList, expectedList);
      }
  
  
      public void expectNoAltTagsInSellerNamesTest(String locale, ArrayList&lt;Object&gt; fixtureData, ArrayList&lt;Object&gt; expectedData) {
          this.locale = locale;
          this.fixtureData = fixtureData;
          this.expectedData = expectedData;
      }
  
      /**
       * Actual test code for this class.  Note the use of 'this.foo' variables,
       * which are stuffed by JUnit's Parameterized Test Runner before execution.
       *
       * There are a number of potential small refactors here.
       *
       * @throws Exception
       */
      @Test  // MST-781
      public void test() throws Exception {
          File htmlPage = named((String) this.fixtureData.get(0));
          assertThat(htmlPage, notNullValue());
  
          OfferList ol = getOfferList(htmlPage);
          assertThat(ol, notNullValue());
  
          int testVal = ol.getOffers().size();
          int expectVal = (Integer)this.expectedData.get(0);
          assertThat(testVal, is(expectVal));
  
          for (IOffer offer : ol.getOffers()) {
              String sellerName = offer.getSellerName();
  
              // look for seller names that have anything other than
              // \w (word chars), \s (whitespace), and [.,'"()&amp;!-]
              // (in short, 'alt="Seller Name' should trigger this
              // @todo change to checking for "alt="
              Pattern pattern = Pattern.compile("[^\\w\\s.,'\"\\(\\)&amp;!-]");
              Matcher matcher = pattern.matcher(sellerName);
  //            System.out.println("Inspecting " + sellerName + ": " + matcher.find());
              assertThat(matcher.find(), is(false));
          }
      }
  
      public void smokeTest() throws Exception {
          // @todo derp
      }
  }
  </code></pre>
  
  <p>Traceback:</p>
  
  <pre><code>java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.List
  at org.junit.runners.Parameterized.getParametersList(Parameterized.java:149)
  at org.junit.runners.Parameterized.&lt;init&gt;(Parameterized.java:135)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
  at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
  at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
  at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
  at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
  at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
  at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
  at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:44)
  at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
  at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
  </code></pre>
  
  <p>Process finished with exit code 255</p>