2014-02-05 14 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) 

我不知道爲什麼和int數組的作品和一個字符串數組沒有。 有沒有辦法通過junitparams將字符串數組傳遞給可變參數測試方法?

編輯:我想寫的是這樣的:

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

,使得所有內部$ -entries傳遞給可變參數的參數。

回答

5

好的,基本上它看起來像是JUnitParams中的一個bug。在下面的原始答案中應用了修復之後,當我們不想要它時,庫仍「解開」String[] - 考慮到在源代碼中進行有條件的打包和解包的數量,看起來作者正試圖爲了自己的利益而過於聰明,或者他們並不知道他們在任何時候都期待着什麼。產生差異的safelyCastParamsToArray,凡在int[]情況下,它傳遞了一個int[]並把它封裝在一個Object[],而在病例String[]它是通過一個String[]這是包裹,因爲它可以轉換爲Object[]了。

可以使其通過使你的方法返回一個雙重包裹陣列,像這樣的工作:

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

或者只是:

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

int[]版本只需要一個單層次的包裝,所以你可以使用:

return $(getIntArray()); 

而不是您當前代碼中的「嘗試雙重包裝,它被可變參數箔所挫敗」。

個人我有點警惕了這一切 - 它有一個明顯的「黑魔法,小爐匠,直到它的工作原理」的感覺不容易出現在乾淨的API ...


原來的答覆

我相信問題是,String[]陣列已經是一個Object[],所以你結束了它沒有被包裹在你想要的方式 - 可變參數的治療參數爲爲整個數組而不是數組中的一個元素。你可以很容易解決這個問題,但:

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

或者只是使用一個轉換:

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

,或者直接忽略在這種情況下,$方法:

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

(我很懷疑你需要$($(...))或者的情況 - 你只是想做一個數組的數組,對嗎?所以只有一個級別的包裝pping是必需的,你只有越來越包裝,無論如何,對於完全相同的原因,你的原始代碼沒有與字符串數組工作的一個級別)。

+0

可變參數應將參數視爲整個數組,因爲實際測試的方法也使用可變參數。我只是想將這個數組傳遞給測試方法。用你的建議JUnit給出了這個錯誤:java.lang.IllegalStateException:嘗試創建類類[Ljava.lang.String;找不到參數匹配(type-wise)參數的構造函數。 – Juergen

+0

@Juergen:事實上它是測試方法中的可變參數,幾乎可以肯定地被測試運行者忽略 - 它只是把它看作一個字符串數組,我認爲它在創建時遇到了麻煩...... –

+0

我可以讓它工作將一個字符串列表傳遞給測試方法,然後將其轉換爲一個數組,然後將該數組傳遞給待測試的方法。但它看起來很醜並且「頭號」...... – Juergen

0

也許zohhak庫可以幫助你。它基於junit params。它允許您僅將註釋中的參數作爲字符串提供,但它允許您輕鬆地爲這些字符串創建自己的自定義分析器。