我正在用java编写一个基本上测试一堆东西的程序......
对于每次通话,我都需要检查NullPointerExceptions
,StackOverflow
,IndexOutOfBounds
等...
我现在每个方法都有这种重复模式:
try {
doSomething();
} catch(NullPointerExceptions npe) {
// prints something
} catch(StackOverflow soe) {
// prints something
} catch(IndexOutOfBounds iob) {
// prints something
}
由于我可以在一个方法中多次调用doSomething()
(使用不同的参数),我不能只将throw
异常备份到main(因为我需要实际运行的下一个测试) )。
我想写一个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
}
}
答案 0 :(得分: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>
,因为您在equals
内呼叫test
。
这称为SAM(单一抽象方法)接口。使用SAM类和接口来模拟lambdas是Java中常见的事件。我甚至听说过他们叫做“SAMbdas”。
编辑:我的解决方案不一定涉及修改现有类:
DoSomething foo = new DoSomething<String>() {
public String doSomething() { return "Hello World"; }
};
test(foo, "Hello World");
答案 1 :(得分:2)
遗憾的是,Lambda尚未出现在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
}
}
答案 2 :(得分:1)
可能会这样:
abstract class Method<R> {
public R run();
}
test(new Method<Result1>() {
public Result1 run() { .... }
}, expectedResult);
答案 3 :(得分:1)
Lambdas将继续努力进入JDK7。如果您想尝试一下,请从Oracle
获取一个早期访问版本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这样的单元测试框架可能会帮助很多。
答案 4 :(得分: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 }