2014-02-05 4 views
5

Рассмотрим этот тестовый класс, работающий с JUnit 4 и JUnitParams:JUnitParams не работает с Струнный массива

import static junitparams.JUnitParamsRunner.$; 
import junitparams.JUnitParamsRunner; 
import junitparams.Parameters; 

import org.junit.Test; 
import org.junit.runner.RunWith; 

@RunWith(JUnitParamsRunner.class) 
public class JUnitParamsExample { 

    private int[] getIntArray() { 
     int array[] = new int[2]; 
     array[0] = 1; 
     array[1] = 2; 
     return array; 
    } 

    public Object getInts() { 
     return $($(getIntArray())); 
    } 

    @Parameters(method = "getInts") 
    @Test 
    public void testIntArray(int... values) { 
     // 
    } 

    private String[] getStringArray() { 
     String array[] = new String[2]; 
     array[0] = "a"; 
     array[1] = "b"; 
     return array; 
    } 

    public Object getStrings() { 
     return $($(getStringArray())); 
    } 

    @Parameters(method = "getStrings") 
    @Test 
    public void testStringArray(String... values) { 
     // 
    } 
} 

Метод испытания testIntArray работает нормально, в то время как testStringArray не делает. Выход ошибки:

java.lang.IllegalArgumentException: Cannot parse parameters. Did you use , as column separator? a 
    at junitparams.internal.InvokeParameterisedMethod.castParamsFromString(InvokeParameterisedMethod.java:51) 
    at junitparams.internal.InvokeParameterisedMethod.<init>(InvokeParameterisedMethod.java:35) 
    at junitparams.internal.ParameterisedTestClassRunner.buildMethodInvoker(ParameterisedTestClassRunner.java:121) 
    at junitparams.internal.ParameterisedTestClassRunner.parameterisedMethodInvoker(ParameterisedTestClassRunner.java:115) 
    at junitparams.JUnitParamsRunner.methodInvoker(JUnitParamsRunner.java:425) 
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:251) 
    at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:405) 
    at junitparams.JUnitParamsRunner.runChild(JUnitParamsRunner.java:383) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
Caused by: java.lang.IllegalArgumentException: Parameter type cannot be handled! Only primitive types and Strings can be used. 
    at junitparams.internal.InvokeParameterisedMethod.castParameterDirectly(InvokeParameterisedMethod.java:171) 
    at junitparams.internal.InvokeParameterisedMethod.castAllParametersToProperTypes(InvokeParameterisedMethod.java:122) 
    at junitparams.internal.InvokeParameterisedMethod.castParamsUsingConverters(InvokeParameterisedMethod.java:101) 
    at junitparams.internal.InvokeParameterisedMethod.castParamsFromString(InvokeParameterisedMethod.java:49) 

Я задаюсь вопросом, почему и ИНТ работы массива и массив строк не делает. Есть ли способ передать строковый массив методу varargs с помощью junitparams?

EDIT: То, что я хотел бы написать что-то вроде этого:

public Object getStrings() { 
     return $($("Hello", "world"), 
       $("Me", "You"), 
       $("Dog", "Cat")); 
} 

, что все внутренние $ -entries передаются переменные аргументы аргумента.

ответ

5

Хорошо, в основном это похоже на ошибку в JUnitParams. После применения исправления в исходном ответе ниже библиотека все еще «разворачивает» String[], когда мы этого не хотим, - учитывая количество условных оберток и разворачивание в источнике, кажется, что либо автор пытается быть слишком умными для собственного блага, или они действительно не знают, чего они ожидают в любой момент. Разница происходит в safelyCastParamsToArray, где в int[] случае это прошло int[] и оборачивает его в Object[], тогда как в String[] случаях он прошел String[], который не обернут, потому что он может быть приведен к Object[] уже.

Вы можете сделать его работу, сделав ваш метод возвращает дважды обернутый массив, например:

return $((Object)$((Object)getStringArray())); 

Или просто:

return new Object[] { new Object[] { getStringArray() } }; 

версия int[] нужна только один уровень упаковки, однако, вы можете просто использовать:

return $(getIntArray()); 

, а не «попытка двойного обертывания, которая была сорвана varargs» в вашем текущем коде.

Лично я несколько настороженно всего этого - он имеет отчетливо выраженную «черную магию, ремесленник, пока она работает» чувство, которое не стремится присутствовать в чистых API, ...


Оригинальный ответ

Я считаю, что проблема заключается в том, что String[] массив уже Object[], так что вы в конечном итоге с ним не заворачивают таким образом, что вы хотите его - обрабатывает переменные аргументы аргумент в качестве целым массивом, а не одним элементом массива.Вы можете исправить это довольно легко, хотя:

public Object getStrings() { 
    Object array = getStringArray(); 
    return $(array); 
} 

Или просто использовать бросок:

public Object getStrings() { 
    return $((Object) getStringArray()); 
} 

Или просто игнорировать метод $ в этом случае:

public Object getStrings() { 
    return new Object[] { getStringArray() }; 
} 

(я очень сомневаюсь что вам нужно $($(...)) в либо case - вы просто пытаетесь создать массив массивов, так? Только один уровень wra pping требуется, и вы только получать один уровень упаковки во всяком случае, именно по той же причине, что исходный код не работает с массивом строк.)

+0

varargs должен рассматривать аргумент как весь массив, так как в текущем тестируемом методе также используется аргумент varargs. Я просто хочу передать этот массив методу тестирования. С вашим предложением JUnit дает эту ошибку: java.lang.IllegalStateException: при попытке создать объект класса класса [Ljava.lang.String; не удалось найти конструктор с аргументами, соответствующими (по типу) тем, которые указаны в параметрах. – Juergen

+0

@Juergen: факт, что это параметр varargs в методе тестирования, почти наверняка остается незамеченным для тестового бегуна - он просто думает об этом как строковый массив, который, я думаю, создает проблемы с созданием ... –

+0

Я могу заставить его работать с передачей строкового списка методу тестирования и последующим преобразованием его в массив, который, в свою очередь, передается тестируемому методу. Но это выглядит уродливо и «накладно» ... – Juergen

0

возможно zohhak библиотека может помочь вам. он основан на параметрах junit. он позволяет вам указывать только параметры в аннотации в виде строки, но это позволяет вам легко создавать собственные собственные синтаксические анализаторы для этих строк.

 Смежные вопросы

  • Нет связанных вопросов^_^