Reputation: 26997
I'm writing a program in java that essentially tests a bunch of things...
For every call, I need to check for NullPointerExceptions
, StackOverflow
, IndexOutOfBounds
, etc...
I have this repeating pattern in each of my methods now:
try {
doSomething();
} catch(NullPointerExceptions npe) {
// prints something
} catch(StackOverflow soe) {
// prints something
} catch(IndexOutOfBounds iob) {
// prints something
}
Since I may call doSomething()
(with different params) multiple times in a single method, I can't just throw
the exception back up to main (because I need the next test to actually run).
I'd like to write a lambda tester that I can pass a function to, but I can't find a way to do this with java :(.
I'd like to do something like:
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
}
}
Upvotes: 2
Views: 584
Reputation: 61081
The best you can do in Java is to use an interface:
interface DoSomething<E extends Comparable<E>> {
E doSomething();
}
Then your test
method can look like this:
private void test(DoSomething<E> m, E expectedValue) {
try {
if(!m.doSomething().equals(expectedValue))
System.out.println("FAILED TEST");
} catch() {
//handle exception
}
}
E
needs to extend Comparable<E>
because you are calling equals
inside of test
.
This is called a SAM (single abstract method) interface. Using SAM classes and interfaces to simulate lambdas is a common occurence in Java. I've even heard them called "SAMbdas".
EDIT: My solution does not necessarily involve modifying existing classes:
DoSomething foo = new DoSomething<String>() {
public String doSomething() { return "Hello World"; }
};
test(foo, "Hello World");
Upvotes: 4
Reputation: 2070
Lambdas are unfortunately not yet present in java. But you can use generic 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
}
}
Upvotes: 2
Reputation: 5566
Lambdas are going to work their way into JDK7. If you want to try it out, grab one of the early access releases from Oracle
http://www.jcp.org/en/jsr/detail?id=335
That said, I don't quite understand the problem. Can you add an example of how you intend to all these methods? Your suggested method sounds like it is on the right track, try:
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 is right, though. A unit testing framework like JUnit would probably help a lothere.
Upvotes: 1
Reputation: 214
If you want to write this yourself, and not JUnit, you could use Reflection to call the method.
So, instead of saying m.run()
you would use 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 }
Upvotes: 0
Reputation: 36349
It could go like this:
abstract class Method<R> {
public R run();
}
test(new Method<Result1>() {
public Result1 run() { .... }
}, expectedResult);
Upvotes: 1