@@ -18,6 +18,7 @@ Modifications copyright (C) 2017 Uber Technologies, Inc.
18
18
package com .uber .cadence .internal .sync ;
19
19
20
20
import static org .junit .Assert .fail ;
21
+ import static org .mockito .Mockito .*;
21
22
import static org .mockito .Mockito .mock ;
22
23
23
24
import com .uber .cadence .WorkflowExecution ;
@@ -28,8 +29,7 @@ Modifications copyright (C) 2017 Uber Technologies, Inc.
28
29
import java .lang .reflect .Method ;
29
30
import java .lang .reflect .Type ;
30
31
import java .time .Duration ;
31
- import java .util .Map ;
32
- import java .util .Optional ;
32
+ import java .util .*;
33
33
import java .util .function .BiPredicate ;
34
34
import java .util .function .Supplier ;
35
35
import org .junit .Before ;
@@ -44,6 +44,8 @@ public class TestActivityEnvironmentInternalTest {
44
44
45
45
private Object testActivityExecutor ;
46
46
47
+ private Object testWorkflowServiceWrapper ;
48
+
47
49
// Helper method to find the inner class
48
50
private Class <?> findTestActivityExecutorClass () {
49
51
for (Class <?> declaredClass : TestActivityEnvironmentInternal .class .getDeclaredClasses ()) {
@@ -54,18 +56,26 @@ private Class<?> findTestActivityExecutorClass() {
54
56
throw new RuntimeException ("Could not find TestActivityExecutor inner class" );
55
57
}
56
58
57
- // Helper method to print all methods
58
- private void printMethods (Class <?> clazz ) {
59
- System .out .println ("Methods for " + clazz .getName () + ":" );
60
- for (Method method : clazz .getDeclaredMethods ()) {
61
- System .out .println (" " + method );
59
+ // Helper method to find the inner class
60
+ private Class <?> findWorkflowServiceWrapperClass () {
61
+ for (Class <?> declaredClass : TestActivityEnvironmentInternal .class .getDeclaredClasses ()) {
62
+ if (declaredClass .getSimpleName ().equals ("WorkflowServiceWrapper" )) {
63
+ return declaredClass ;
64
+ }
62
65
}
66
+ throw new RuntimeException ("Could not find WorkflowServiceWrapper inner class" );
63
67
}
64
68
65
69
@ Before
66
70
public void setUp () {
67
71
MockitoAnnotations .openMocks (this );
68
72
73
+ setupActivityExecutor ();
74
+
75
+ setupWorkflowServiceWrapper ();
76
+ }
77
+
78
+ private void setupActivityExecutor () {
69
79
try {
70
80
// Find the inner class first
71
81
Class <?> innerClass = findTestActivityExecutorClass ();
@@ -83,16 +93,63 @@ public void setUp() {
83
93
84
94
// Create the instance
85
95
testActivityExecutor = constructor .newInstance (outerInstance , mockWorkflowService , mockNext );
96
+ } catch (Exception e ) {
97
+ e .printStackTrace ();
98
+ throw new RuntimeException ("Failed to set up test: " + e .getMessage (), e );
99
+ }
100
+ }
86
101
87
- // Debug print the class and methods
88
- System .out .println ("TestActivityExecutor class: " + innerClass );
89
- printMethods (innerClass );
102
+ private void setupWorkflowServiceWrapper () {
103
+ try {
104
+ // Find the inner class first
105
+ Class <?> innerClass = findWorkflowServiceWrapperClass ();
106
+
107
+ // Get the constructor with the specific parameter types
108
+ Constructor <?> constructor =
109
+ innerClass .getDeclaredConstructor (
110
+ TestActivityEnvironmentInternal .class , IWorkflowService .class );
111
+ constructor .setAccessible (true );
112
+
113
+ // Create an instance of the outer class
114
+ TestActivityEnvironmentInternal outerInstance = mock (TestActivityEnvironmentInternal .class );
115
+
116
+ // Create the instance
117
+ testWorkflowServiceWrapper = constructor .newInstance (outerInstance , mockWorkflowService );
90
118
} catch (Exception e ) {
91
119
e .printStackTrace ();
92
120
throw new RuntimeException ("Failed to set up test: " + e .getMessage (), e );
93
121
}
94
122
}
95
123
124
+ @ Test
125
+ public void testWorkflowServiceWrapperMethodDelegation () throws Exception {
126
+ // Prepare test cases
127
+ List <MethodTestCase > testCases = prepareMethodTestCases ();
128
+
129
+ System .out .println (testCases );
130
+
131
+ // Test each method
132
+ for (MethodTestCase testCase : testCases ) {
133
+ try {
134
+ // Find the method on the wrapper
135
+ Method wrapperMethod =
136
+ testWorkflowServiceWrapper
137
+ .getClass ()
138
+ .getMethod (testCase .methodName , testCase .parameterTypes );
139
+
140
+ // Invoke the method on the wrapper
141
+ wrapperMethod .invoke (testWorkflowServiceWrapper , testCase .arguments );
142
+
143
+ // Generic verification using reflection
144
+ verifyMethodInvocation (mockWorkflowService , testCase );
145
+
146
+ } catch (Exception e ) {
147
+ // Rethrow to fail the test if any unexpected exception occurs
148
+ throw new AssertionError ("Failed to test method: " + testCase .methodName , e );
149
+ }
150
+ }
151
+ }
152
+
96
153
@ Test
97
154
public void testAllMethodsThrowUnsupportedOperationException () throws Exception {
98
155
// Define test cases for different methods
@@ -232,4 +289,72 @@ private static class MethodTestCase {
232
289
this .arguments = arguments ;
233
290
}
234
291
}
292
+
293
+ /** Generic method to verify method invocation on mock */
294
+ private void verifyMethodInvocation (Object mockObject , MethodTestCase testCase ) throws Exception {
295
+ // Use Mockito's verify with reflection
296
+ if (testCase .arguments .length == 0 ) {
297
+ // For methods with no arguments
298
+ verify (mockObject ).getClass ().getMethod (testCase .methodName ).invoke (mockObject );
299
+ } else {
300
+ // For methods with arguments
301
+ Method verifyMethod = org .mockito .Mockito .class .getMethod ("verify" , Object .class );
302
+ Object verifiedMock = verifyMethod .invoke (null , mockObject );
303
+
304
+ // Invoke the method on the verified mock
305
+ verifiedMock
306
+ .getClass ()
307
+ .getMethod (testCase .methodName , testCase .parameterTypes )
308
+ .invoke (verifiedMock , testCase .arguments );
309
+ }
310
+ }
311
+
312
+ /** Prepares test cases for all methods in IWorkflowService */
313
+ private List <MethodTestCase > prepareMethodTestCases () throws Exception {
314
+ List <MethodTestCase > testCases = new ArrayList <>();
315
+
316
+ // You can add more methods here as needed
317
+ // Dynamically discover and add more methods from IWorkflowService if required
318
+ Method [] allMethods = IWorkflowService .class .getMethods ();
319
+ for (Method method : allMethods ) {
320
+ testCases .add (createDefaultMethodTestCase (method ));
321
+ }
322
+ return testCases ;
323
+ }
324
+
325
+ /** Creates a default MethodTestCase for a given method */
326
+ private MethodTestCase createDefaultMethodTestCase (Method method ) throws Exception {
327
+ Class <?>[] parameterTypes = method .getParameterTypes ();
328
+ Object [] arguments = new Object [parameterTypes .length ];
329
+
330
+ for (int i = 0 ; i < parameterTypes .length ; i ++) {
331
+ arguments [i ] = createDefaultArgument (parameterTypes [i ]);
332
+ }
333
+
334
+ return new MethodTestCase (method .getName (), parameterTypes , arguments );
335
+ }
336
+
337
+ /** Creates a default argument for different parameter types */
338
+ private Object createDefaultArgument (Class <?> type ) throws Exception {
339
+ if (type .isPrimitive ()) {
340
+ if (type == boolean .class ) return false ;
341
+ if (type == char .class ) return '\u0000' ;
342
+ if (type == byte .class ) return (byte ) 0 ;
343
+ if (type == short .class ) return (short ) 0 ;
344
+ if (type == int .class ) return 0 ;
345
+ if (type == long .class ) return 0L ;
346
+ if (type == float .class ) return 0.0f ;
347
+ if (type == double .class ) return 0.0d ;
348
+ }
349
+
350
+ // For non-primitive types, try to create an empty instance
351
+ if (type .getConstructors ().length > 0
352
+ && Arrays .stream (type .getConstructors ())
353
+ .anyMatch (constructor -> constructor .getParameterCount () == 0 )) {
354
+ return type .getDeclaredConstructor ().newInstance ();
355
+ }
356
+
357
+ // Fallback for complex types
358
+ return null ;
359
+ }
235
360
}
0 commit comments