Skip to content

Commit 9274531

Browse files
authored
test: Add test coverage for ChatClientObservationContext (#4124)
Signed-off-by: Oleksandr Klymenko <[email protected]>
1 parent 85c194c commit 9274531

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

spring-ai-client-chat/src/test/java/org/springframework/ai/chat/client/observation/ChatClientObservationContextTests.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,114 @@ void whenAdvisorsWithNullElementsThenReturn() {
7474
.hasMessageContaining("advisors cannot contain null elements");
7575
}
7676

77+
@Test
78+
void whenNullRequestThenThrowException() {
79+
assertThatThrownBy(() -> ChatClientObservationContext.builder().request(null).build())
80+
.isInstanceOf(IllegalArgumentException.class);
81+
}
82+
83+
@Test
84+
void whenValidAdvisorsListThenReturn() {
85+
List<Advisor> advisors = List.of(mock(Advisor.class), mock(Advisor.class));
86+
87+
var observationContext = ChatClientObservationContext.builder()
88+
.request(ChatClientRequest.builder().prompt(new Prompt()).build())
89+
.advisors(advisors)
90+
.build();
91+
92+
assertThat(observationContext).isNotNull();
93+
assertThat(observationContext.getAdvisors()).hasSize(2);
94+
// Check that advisors are present, but don't assume exact ordering or same
95+
// instances
96+
assertThat(observationContext.getAdvisors()).isNotNull().isNotEmpty();
97+
}
98+
99+
@Test
100+
void whenAdvisorsModifiedAfterBuildThenContextMayBeUnaffected() {
101+
List<Advisor> advisors = new ArrayList<>();
102+
advisors.add(mock(Advisor.class));
103+
104+
var observationContext = ChatClientObservationContext.builder()
105+
.request(ChatClientRequest.builder().prompt(new Prompt()).build())
106+
.advisors(advisors)
107+
.build();
108+
109+
int originalSize = observationContext.getAdvisors().size();
110+
111+
// Try to modify original list
112+
advisors.add(mock(Advisor.class));
113+
114+
// Check if context is affected or not - both are valid implementations
115+
int currentSize = observationContext.getAdvisors().size();
116+
// Defensive copy was made
117+
// Same reference used
118+
assertThat(currentSize).satisfiesAnyOf(size -> assertThat(size).isEqualTo(originalSize),
119+
size -> assertThat(size).isEqualTo(originalSize + 1));
120+
}
121+
122+
@Test
123+
void whenGetAdvisorsCalledThenReturnsValidCollection() {
124+
List<Advisor> advisors = List.of(mock(Advisor.class));
125+
126+
var observationContext = ChatClientObservationContext.builder()
127+
.request(ChatClientRequest.builder().prompt(new Prompt()).build())
128+
.advisors(advisors)
129+
.build();
130+
131+
var returnedAdvisors = observationContext.getAdvisors();
132+
133+
// Just verify we get a valid collection back, using var to handle any return type
134+
assertThat(returnedAdvisors).isNotNull();
135+
assertThat(returnedAdvisors).hasSize(1);
136+
}
137+
138+
@Test
139+
void whenRequestWithNullPromptThenThrowException() {
140+
assertThatThrownBy(() -> ChatClientRequest.builder().prompt(null).build())
141+
.isInstanceOf(IllegalArgumentException.class);
142+
}
143+
144+
@Test
145+
void whenEmptyAdvisorsListThenReturn() {
146+
var observationContext = ChatClientObservationContext.builder()
147+
.request(ChatClientRequest.builder().prompt(new Prompt()).build())
148+
.advisors(List.of())
149+
.build();
150+
151+
assertThat(observationContext).isNotNull();
152+
assertThat(observationContext.getAdvisors()).isEmpty();
153+
}
154+
155+
@Test
156+
void whenGetRequestThenReturnsSameInstance() {
157+
ChatClientRequest request = ChatClientRequest.builder().prompt(new Prompt("Test prompt")).build();
158+
159+
var observationContext = ChatClientObservationContext.builder().request(request).build();
160+
161+
assertThat(observationContext.getRequest()).isEqualTo(request);
162+
assertThat(observationContext.getRequest()).isSameAs(request);
163+
}
164+
165+
@Test
166+
void whenBuilderReusedThenReturnDifferentInstances() {
167+
var builder = ChatClientObservationContext.builder()
168+
.request(ChatClientRequest.builder().prompt(new Prompt()).build());
169+
170+
var context1 = builder.build();
171+
var context2 = builder.build();
172+
173+
assertThat(context1).isNotSameAs(context2);
174+
}
175+
176+
@Test
177+
void whenNoAdvisorsSpecifiedThenGetAdvisorsReturnsEmptyOrNull() {
178+
var observationContext = ChatClientObservationContext.builder()
179+
.request(ChatClientRequest.builder().prompt(new Prompt()).build())
180+
.build();
181+
182+
// Should return either empty list or null when no advisors specified
183+
assertThat(observationContext.getAdvisors()).satisfiesAnyOf(advisors -> assertThat(advisors).isNull(),
184+
advisors -> assertThat(advisors).isEmpty());
185+
}
186+
77187
}

0 commit comments

Comments
 (0)