2011-03-27 55 views
2

我用Java編寫,基本上測試了一堆東西的節目......乾涸的Java(lambda函數?)

對於每一個電話,我需要檢查NullPointerExceptionsStackOverflowIndexOutOfBounds等。 ..

我在我的每一個方法現在這個重複模式:

try { 
    doSomething(); 
} catch(NullPointerExceptions npe) { 
    // prints something 
} catch(StackOverflow soe) { 
    // prints something 
} catch(IndexOutOfBounds iob) { 
    // prints something 
} 

由於我可以調用doSomething()(具有不同PARAMS)多次在一個單一的方法,我不能只是throw的EXC eption備份到主要(因爲我需要下一個測試來實際運行)。

我想寫一個lambda測試,我可以傳遞給一個函數,但我不能找到一種方法,用java :(做到這一點

我想這樣做:

private void test(Method m, E expectedValue) { 
    try { 
    if(!m.run().equals(expectedValue)) 
     System.out.println("FAILED TEST: "+m.name()+". Value was "+m.run()+", should have been "+expectedValue); 
    } catch() { 
    // see above 
    } 
} 
+3

你可以使用JUnit嗎?這對你來說或多或少。 – RoflcoptrException 2011-03-27 17:25:53

+0

不,JUnit在這種情況下是不可行的,否則我會使用它... – sethvargo 2011-03-27 17:30:04

+1

我不明白這個問題。也不明白爲什麼JUnit不適合。 – Bozho 2011-03-27 17:32:46

回答

4

,你可以在Java中做的最好的是使用一個接口:

interface DoSomething<E extends Comparable<E>> { 
    E doSomething(); 
} 

然後你test方法可以是這樣的:

private void test(DoSomething<E> m, E expectedValue) { 
    try { 
    if(!m.doSomething().equals(expectedValue)) 
     System.out.println("FAILED TEST"); 
    } catch() { 
    //handle exception 
    } 
} 

E需要延續Comparable<E>,因爲你在呼喚equalstest內。

這被稱爲SAM(單抽象方法)接口。使用SAM類和接口來模擬lambda是Java中常見的事件。我甚至聽說過他們叫「SAMbdas」。

編輯:我的解決方案並不一定涉及修改現有的類:

DoSomething foo = new DoSomething<String>() { 
    public String doSomething() { return "Hello World"; } 
}; 
test(foo, "Hello World"); 
+0

然而,這有一個缺點,即現有的類必須被修改(即實現DoSomething),這並不總是可能的(或者希望的)。 – Ingo 2011-03-27 20:34:21

+0

@Ingo我不同意。您可以使用類似於解決方案的匿名內部類。看我的編輯。 – dbyrne 2011-03-27 20:42:33

+0

@dbyme - 的確,我糾正了。看起來你應該得到你的+1。 :) – Ingo 2011-03-27 20:51:59

1

這可能是這樣的:

abstract class Method<R> { 
    public R run(); 
} 


test(new Method<Result1>() { 
     public Result1 run() { .... } 
    }, expectedResult); 
+0

小修正:'R'需要延長'可比'# – dbyrne 2011-03-27 17:33:56

+0

可比較或可比較?或者就此而言只有Comparable? – sethvargo 2011-03-27 17:34:53

+0

在英戈的回答'可比較',在我的答案'可比較';) – dbyrne 2011-03-27 17:35:36

0

如果你想這個自己編寫的,而不是JUnit的,你可以使用Reflection調用該方法。

所以,與其說m.run()你可以使用java.lang.reflect.Method#invoke

 
try { 
    method.invoke(obj, arg1, arg2,...); 
} catch (Exception e) { 
    // there are several Reflection exceptions you also need to deal with 
} 
1

Lambda表達式要自己的方式工作到JDK7。如果你想嘗試一下,抓住早期試用版本之一甲骨文

http://www.jcp.org/en/jsr/detail?id=335

這麼說,我不太明白的問題。你可以添加一個你如何打算使用所有這些方法的例子嗎?您的建議方法聽起來像是在正確的軌道上,請嘗試:

private void test(Method m, Object target, Object[] args, E expectedValue) { 
    try { 
    if(!m.invoke(target, args).equals(expectedValue)) 
     System.out.println("FAILED TEST: "+m.name()+". Value was "+m.run()+", should have been "+expectedValue); 
    } catch() { 
    // see above 
    } 
} 

雖然Gus Bosman是正確的。像JUnit這樣的單元測試框架可能會有所幫助。

+0

是...但這需要在多臺機器上工作,不只是我的... – sethvargo 2011-03-27 17:35:13

+0

JUnit不是專門爲您的機器提供。例如,我也使用它 – RoflcoptrException 2011-03-27 17:39:33

+0

不......我不能使用JUnit,但我也不能使用預發佈的Java,因爲它在多個機器上 – sethvargo 2011-03-27 17:40:39

2

不幸的是,lambdas還沒有出現在java中。但是你可以使用通用的java.util.concurrent.Callable:

private <T> void test(Callable<T> c, T expectedValue) { 
     try { 
     if(!c.call().equals(expectedValue)) 
      System.out.println("FAILED TEST: "+c+". Value was "+c.call()+", should have been "+expectedValue); 
     } catch(Exception ex) { 
     // see above 
     } 
    }