2011-03-27 58 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 
     } 
    }