…lines 1–10 unchanged (10 lines)
11 }
12
13 public <T> T newInstance(Class<T> cls) {
14 if (outerClassInstance == null) {
15 return noArgConstructor(cls);
16 }
17 return withParams(cls, outerClassInstance);
18 }
19
20 private static <T> T withParams(Class<T> cls, Object... params) {
21 try {
22 //this is kind of overengineered because we don't need to support more params
23 //however, I know we will be needing it :)
24 for (Constructor<?> constructor : cls.getDeclaredConstructors()) {
25 Class<?>[] types = constructor.getParameterTypes();
26 if (paramsMatch(types, params)) {
27 return (T) constructor.newInstance(params);
28 }
29 }
30 } catch (Exception e) {
31 throw paramsException(cls, e);
32 }
33 throw paramsException(cls, null);
34 }
35
36 private static <T> InstantationException paramsException(Class<T> cls, Exception e) {
37 return new InstantationException("Unable to create mock instance of '"
38 + cls.getSimpleName() + "'.\nPlease ensure that the outer instance has correct type and that the target class has parameter-less constructor.", e);
39 }
40
41 private static boolean paramsMatch(Class<?>[] types, Object[] params) {
42 if (params.length != types.length) {
43 return false;
44 }
45 for (int i = 0; i < params.length; i++) {
46 if (!types[i].isInstance(params[i])) {
47 return false;
48 }
49 }
50 return true;
51 }
52
53 private static <T> T noArgConstructor(Class<T> cls) {
54 try {
55 return cls.newInstance();
56 } catch (Exception e) {
57 throw new InstantationException("Unable to create mock instance of '"
…lines 58–62 unchanged (5 lines)