/* * Galaxy * Copyright (C) 2012 Parallel Universe Software Co. * * This file is part of Galaxy. * * Galaxy is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * Galaxy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with Galaxy. If not, see <http://www.gnu.org/licenses/>. */ package co.paralleluniverse.galaxy.test; import com.google.common.primitives.Primitives; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.mockito.ArgumentCaptor; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import org.mockito.verification.VerificationMode; /** * * @author pron */ public class MockitoUtil { public static <T> Placeholder<T> arg(Class<T> clazz) { return new Placeholder(clazz); } public static Object capture(Object mock, String methodName, Object... args) { return capture(mock, times(1), methodName, args); } public static Object capture(Object mock, VerificationMode mode, String methodName, Object... args) { try { int argIndex = -1; Class argType = null; Class[] types = new Class[args.length]; for (int i = 0; i < args.length; i++) { if (args[i] instanceof Placeholder) { if (argType != null) throw new IllegalArgumentException("More than one argument placeholder provided"); argIndex = i; argType = ((Placeholder) args[i]).clazz; types[i] = argType; } else types[i] = Primitives.unwrap(args[i].getClass()); } final Method method = mock.getClass().getDeclaredMethod(methodName, types); method.setAccessible(true); ArgumentCaptor captor = ArgumentCaptor.forClass(argType); method.invoke(verify(mock, mode), replace(args, argIndex, captor)); return captor.getValue(); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { throw new RuntimeException(ex.getCause()); } catch (NoSuchMethodException ex) { throw new RuntimeException(ex); } catch (SecurityException ex) { throw new RuntimeException(ex); } } private static Object[] replace(Object[] args, int index, ArgumentCaptor captor) { Object[] res = new Object[args.length]; for(int i=0; i<args.length; i++) { if(i == index) res[i] = captor.capture(); else res[i] = eq(args[i]); } return res; } private static class Placeholder<T> { final Class<T> clazz; public Placeholder(Class<T> clazz) { this.clazz = clazz; } } private MockitoUtil() { } }