diff options
author | Marc Schroeder <msch@google.com> | 2012-08-09 18:18:40 -0700 |
---|---|---|
committer | Marc Schroeder <msch@google.com> | 2012-08-13 12:51:37 -0700 |
commit | 00e20ef3c702f7388c98bdeee300d218c7871f4d (patch) | |
tree | 0c405bb0663216e90a092cd1ed187cc38634c74b | |
parent | c8e1dd4c1418f6876ab47e6d698b0003cd0f651e (diff) | |
download | littlemock-00e20ef3c702f7388c98bdeee300d218c7871f4d.tar.gz |
Support for primitive (non-Object) captors in littlemock
The LittleMock captor does not support primitive types
such as int -- the respective code crashes with a
NullPointerException.
This CL implements an approach for avoiding this problem
in a way that stays as close to Mockito syntax as possible:
- the generic capture() works for primitives as well;
- we create the ArgumentCaptor with the same basic approach
as Mockito does it, from a class object of type T:
<T> ArgumentCaptor<T> LittleMock.createCaptor(Class<T> clazz)
( Mockito uses ArgumentCaptor.forClass(Class<T> clazz) )
Change-Id: Ie8c234466e63adf533d863be2b74d3516ecc9947
-rw-r--r-- | src/com/google/testing/littlemock/ArgumentCaptor.java | 1 | ||||
-rw-r--r-- | src/com/google/testing/littlemock/LittleMock.java | 42 |
2 files changed, 43 insertions, 0 deletions
diff --git a/src/com/google/testing/littlemock/ArgumentCaptor.java b/src/com/google/testing/littlemock/ArgumentCaptor.java index 99e9b55..ff75246 100644 --- a/src/com/google/testing/littlemock/ArgumentCaptor.java +++ b/src/com/google/testing/littlemock/ArgumentCaptor.java @@ -34,4 +34,5 @@ public interface ArgumentCaptor<T extends Object> extends LittleMock.ArgumentMat /** Use this argument captor to perform the capture. */ public T capture(); + } diff --git a/src/com/google/testing/littlemock/LittleMock.java b/src/com/google/testing/littlemock/LittleMock.java index fc6c527..ebd44ab 100644 --- a/src/com/google/testing/littlemock/LittleMock.java +++ b/src/com/google/testing/littlemock/LittleMock.java @@ -323,12 +323,27 @@ public class LittleMock { return new ArgumentCaptorImpl<T>(); } + /** + * Create a correctly typed ArgumentCaptor that also works for primitive types. + * For example, to capture an int, use + * <code>ArgumentCaptor<Integer> c = createCaptor(Integer.class);</code> + */ + public static <T> ArgumentCaptor<T> createCaptor(Class<T> clazz) { + return new ArgumentCaptorImpl<T>(clazz); + } + /** Implementation of the {@link ArgumentCaptor} interface. */ private static class ArgumentCaptorImpl<T extends Object> implements ArgumentCaptor<T> { private final ArrayList<T> mAllValues = new ArrayList<T>(); private T mValue; + private Class<T> mClass; private ArgumentCaptorImpl() { + mClass = null; + } + + private ArgumentCaptorImpl(Class<T> clazz) { + mClass = clazz; } public void setValue(T value) { @@ -348,9 +363,36 @@ public class LittleMock { @Override public T capture() { + if (mClass != null) { + if (Integer.class.isAssignableFrom(mClass)) { + return (T) LittleMock.<Integer>addMatcher(this, 0); + } + if (Float.class.isAssignableFrom(mClass)) { + return (T) LittleMock.<Float>addMatcher(this, 0f); + } + if (Double.class.isAssignableFrom(mClass)) { + return (T) LittleMock.<Double>addMatcher(this, 0.0); + } + if (Boolean.class.isAssignableFrom(mClass)) { + return (T) LittleMock.<Boolean>addMatcher(this, false); + } + if (Short.class.isAssignableFrom(mClass)) { + return (T) LittleMock.<Short>addMatcher(this, (short) 0); + } + if (Character.class.isAssignableFrom(mClass)) { + return (T) LittleMock.<Character>addMatcher(this, '\u0000'); + } + if (Long.class.isAssignableFrom(mClass)) { + return (T) LittleMock.<Long>addMatcher(this, 0L); + } + if (Byte.class.isAssignableFrom(mClass)) { + return (T) LittleMock.<Byte>addMatcher(this, (byte) 0); + } + } return LittleMock.<T>addMatcher(this, null); } + @Override public boolean matches(Object value) { // A capture always matches any argument. |