1
+
2
+ /*
3
+ * Copyright 2023-2025 the original author or authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * https://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ package org .springframework .ai .tool .method ;
19
+
20
+ import java .lang .reflect .Method ;
21
+
22
+ import org .junit .jupiter .api .Test ;
23
+
24
+ import org .springframework .ai .tool .annotation .Tool ;
25
+ import org .springframework .ai .tool .definition .DefaultToolDefinition ;
26
+ import org .springframework .ai .tool .definition .ToolDefinition ;
27
+ import org .springframework .ai .tool .execution .ToolExecutionException ;
28
+
29
+ import static org .assertj .core .api .Assertions .assertThat ;
30
+ import static org .assertj .core .api .Assertions .assertThatThrownBy ;
31
+
32
+ /**
33
+ * Unit tests for {@link MethodToolCallback}.
34
+ *
35
+ * @author Thomas Vitale
36
+ */
37
+ class MethodToolCallbackTests {
38
+
39
+ @ Test
40
+ void shouldThrowToolExecutionExceptionForInvalidEnumArgument () throws Exception {
41
+ // Given
42
+ TestToolClass testTool = new TestToolClass ();
43
+ Method method = TestToolClass .class .getDeclaredMethod ("processOrder" , OrderType .class );
44
+ ToolDefinition toolDefinition = DefaultToolDefinition .builder ()
45
+ .name ("processOrder" )
46
+ .description ("Process an order" )
47
+ .inputSchema ("{}" )
48
+ .build ();
49
+
50
+ MethodToolCallback callback = new MethodToolCallback (toolDefinition , null , method , testTool , null );
51
+
52
+ // When/Then - Invalid enum value should throw ToolExecutionException
53
+ assertThatThrownBy (() -> callback .call ("{\" orderType\" : \" INVALID_TYPE\" }" ))
54
+ .isInstanceOf (ToolExecutionException .class )
55
+ .hasCauseInstanceOf (IllegalArgumentException .class )
56
+ .hasMessageContaining ("No enum constant" );
57
+
58
+ // Verify the ToolExecutionException contains the correct tool definition
59
+ try {
60
+ callback .call ("{\" orderType\" : \" INVALID_TYPE\" }" );
61
+ }
62
+ catch (ToolExecutionException ex ) {
63
+ assertThat (ex .getToolDefinition ()).isEqualTo (toolDefinition );
64
+ assertThat (ex .getCause ()).isInstanceOf (IllegalArgumentException .class );
65
+ }
66
+ }
67
+
68
+ @ Test
69
+ void shouldSucceedWithValidEnumArgument () throws Exception {
70
+ // Given
71
+ TestToolClass testTool = new TestToolClass ();
72
+ Method method = TestToolClass .class .getDeclaredMethod ("processOrder" , OrderType .class );
73
+ ToolDefinition toolDefinition = DefaultToolDefinition .builder ()
74
+ .name ("processOrder" )
75
+ .description ("Process an order" )
76
+ .inputSchema ("{}" )
77
+ .build ();
78
+
79
+ MethodToolCallback callback = new MethodToolCallback (toolDefinition , null , method , testTool , null );
80
+
81
+ // When
82
+ String result = callback .call ("{\" orderType\" : \" ONE_DAY\" }" );
83
+
84
+ // Then
85
+ assertThat (result ).isEqualTo ("\" Processing ONE_DAY order\" " );
86
+ }
87
+
88
+ // Test classes
89
+ static class TestToolClass {
90
+
91
+ @ Tool (description = "Process an order with the specified delivery type" )
92
+ public String processOrder (OrderType orderType ) {
93
+ return "Processing " + orderType + " order" ;
94
+ }
95
+
96
+ }
97
+
98
+ enum OrderType {
99
+
100
+ ONE_DAY , TWO_DAY , THREE_DAY
101
+
102
+ }
103
+
104
+ }
0 commit comments