From b08fc4d823a38c3948da6a059b76bf1cf46ac73f Mon Sep 17 00:00:00 2001
From: roost-io <8110509+mgdevstack@users.noreply.github.com>
Date: Fri, 8 May 2026 10:30:04 +0530
Subject: [PATCH] Unit test generated by RoostGPT
Using AI Model gpt-5
---
core/pom.xml | 21 +-
.../adk/models/ClaudeGenerateContentTest.java | 340 ++++++++++++++++++
pom.xml | 79 +++-
3 files changed, 416 insertions(+), 24 deletions(-)
create mode 100644 core/src/test/java/com/google/adk/models/ClaudeGenerateContentTest.java
diff --git a/core/pom.xml b/core/pom.xml
index fe65715f3..7d2032c7e 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -1,4 +1,4 @@
-
+
4.0.0
-
com.google.adk
google-adk-parent
- 0.4.1-SNAPSHOT
+ 0.4.1-SNAPSHOT
+
-
google-adk
Agent Development Kit
Agent Development Kit: an open-source, code-first toolkit designed to simplify building, evaluating, and deploying advanced AI agents anywhere.
-
-
-
com.anthropic
@@ -201,6 +197,15 @@
maven-compiler-plugin
+
+ io.spring.javaformat
+ spring-javaformat-maven-plugin
+ 0.0.40
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/core/src/test/java/com/google/adk/models/ClaudeGenerateContentTest.java b/core/src/test/java/com/google/adk/models/ClaudeGenerateContentTest.java
new file mode 100644
index 000000000..9fe584dd0
--- /dev/null
+++ b/core/src/test/java/com/google/adk/models/ClaudeGenerateContentTest.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test unit-java-adk using AI Type Azure Open AI and AI Model gpt-5
+
+ROOST_METHOD_HASH=generateContent_bc4a182290
+ROOST_METHOD_SIG_HASH=generateContent_c08b9769fe
+
+Scenario 1: Basic request with a single user text message, no tools, no system instruction, using default model and default maxTokens
+
+Details:
+ TestName: basicUserTextNoToolsUsesDefaults
+ Description: This test verifies that generateContent builds MessageCreateParams with the expected defaults when the request has one user text Content, no tools, no system instruction, and no model override. It ensures model falls back to the Claude instance’s model(), maxTokens uses the default (8192), no toolChoice is set, and the messages list includes the user text with Role.USER.
+
+Execution:
+ Arrange: Prepare a mock AnthropicClient with messages().create(...) returning a Message containing a simple text ContentBlock. Construct a Claude instance with a model name and the mock client. Build an LlmRequest mock where contents() returns a single Content with a text Part and role “user”, config() is empty, tools() is empty, and model() is empty.
+ Act: Call generateContent(llmRequest, false).
+ Assert: Verify messages().create(...) is invoked exactly once and capture the MessageCreateParams to confirm it contains: the instance model(), system is an empty string, maxTokens = 8192, messages list with one element having Role.USER and the provided text, and no toolChoice or tools configured. Verify the returned Flowable emits exactly one LlmResponse and completes.
+
+Validation:
+ Ensures correct defaulting behavior: no system text, no tools when none requested, default model fallback, and default maxTokens usage. Confirms the method produces a single response event and completes successfully in the basic scenario.
+
+*/
+
+// ********RoostGPT********
+
+package com.google.adk.models;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.anthropic.client.AnthropicClient;
+import com.anthropic.models.messages.Message;
+import com.anthropic.models.messages.MessageCreateParams;
+import com.anthropic.models.messages.MessageParam;
+import com.anthropic.models.messages.MessageParam.Role;
+import com.anthropic.models.messages.ToolChoice;
+import com.anthropic.models.messages.ToolUnion;
+import com.google.adk.tools.BaseTool;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.genai.types.Content;
+import com.google.genai.types.GenerateContentConfig;
+import com.google.genai.types.Part;
+import io.reactivex.rxjava3.core.Flowable;
+import io.reactivex.rxjava3.subscribers.TestSubscriber;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+public abstract class ClaudeGenerateContentTest extends BaseLlm {
+
+ public ClaudeGenerateContentTest() {
+ super("test-model");
+ }
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private AnthropicClient anthropicClient;
+
+ @InjectMocks
+ private Claude unusedClaudeForInjection = new Claude("test-model", anthropicClient); // Not
+
+ // used
+ // directly
+ // in
+ // tests
+
+ @Test
+ @Tag("valid")
+ public void testBasicUserTextNoToolsUsesDefaults() {
+ // Arrange
+ String modelName = "claude-3-opus"; // TODO: Change model name if needed
+ Claude claude = new Claude(modelName, anthropicClient);
+ Content userContent =
+ Content.builder()
+ .role("user")
+ .parts(ImmutableList.of(Part.builder().text("Hello, Claude!").build()))
+ .build();
+ LlmRequest llmRequest = LlmRequest.builder().contents(ImmutableList.of(userContent)).build();
+ Message mockMessage = Mockito.mock(Message.class);
+ when(mockMessage.content()).thenReturn(ImmutableList.of());
+ when(anthropicClient.messages().create(any(MessageCreateParams.class))).thenReturn(mockMessage);
+ // Act
+ Flowable flowable = claude.generateContent(llmRequest, false);
+ TestSubscriber ts = flowable.test();
+ // Assert output Flowable behavior
+ ts.assertComplete();
+ ts.assertValueCount(1);
+ List values = ts.values();
+ assertEquals(1, (int) values.size());
+ assertNotNull(values.get(0));
+ // Assert request sent to Anthropic
+ ArgumentCaptor paramsCaptor =
+ ArgumentCaptor.forClass(MessageCreateParams.class);
+ verify(anthropicClient.messages(), times(1)).create(paramsCaptor.capture());
+ MessageCreateParams params = paramsCaptor.getValue();
+ assertEquals(claude.model(), params.model());
+ assertEquals("", params.system());
+ assertEquals(8192, (int) params.maxTokens());
+ List sentMessages = params.messages();
+ assertNotNull(sentMessages);
+ assertEquals(1, (int) sentMessages.size());
+ MessageParam mp = sentMessages.get(0);
+ assertEquals(Role.USER, mp.role());
+ assertNotNull(mp.content());
+ // Tool choice and tools should not be set when no tools provided
+ Optional toolChoiceOpt = params.toolChoice();
+ assertTrue(toolChoiceOpt.isEmpty());
+ Optional> toolsListOpt = params.tools();
+ assertTrue(toolsListOpt.isEmpty() || toolsListOpt.get().isEmpty());
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testSystemInstructionJoinsMultipleTextParts() {
+ // Arrange
+ String modelName = "claude-3-sonnet"; // TODO: Change model name if needed
+ Claude claude = new Claude(modelName, anthropicClient);
+ Content userContent =
+ Content.builder()
+ .role("user")
+ .parts(ImmutableList.of(Part.builder().text("Run task").build()))
+ .build();
+ Content systemInstruction =
+ Content.builder()
+ .parts(
+ ImmutableList.of(
+ Part.builder().text("You are a helpful assistant.").build(),
+ Part.builder().text("Answer concisely.").build()))
+ .build();
+ GenerateContentConfig mockConfig = Mockito.mock(GenerateContentConfig.class);
+ when(mockConfig.systemInstruction()).thenReturn(Optional.of(systemInstruction));
+ when(mockConfig.tools()).thenReturn(Optional.empty());
+ // Mock LlmRequest directly to avoid builder signature mismatch for config
+ LlmRequest llmRequest = Mockito.mock(LlmRequest.class);
+ when(llmRequest.contents()).thenReturn(ImmutableList.of(userContent));
+ when(llmRequest.config()).thenReturn(Optional.of(mockConfig));
+ when(llmRequest.tools()).thenReturn(ImmutableMap.of());
+ when(llmRequest.model()).thenReturn(Optional.empty());
+ Message mockMessage = Mockito.mock(Message.class);
+ when(mockMessage.content()).thenReturn(ImmutableList.of());
+ when(anthropicClient.messages().create(any(MessageCreateParams.class))).thenReturn(mockMessage);
+ // Act
+ Flowable flowable = claude.generateContent(llmRequest, false);
+ TestSubscriber ts = flowable.test();
+ // Assert Flowable behavior
+ ts.assertComplete();
+ ts.assertValueCount(1);
+ assertNotNull(ts.values().get(0));
+ // Assert params
+ ArgumentCaptor paramsCaptor =
+ ArgumentCaptor.forClass(MessageCreateParams.class);
+ verify(anthropicClient.messages(), times(1)).create(paramsCaptor.capture());
+ MessageCreateParams params = paramsCaptor.getValue();
+ assertEquals(claude.model(), params.model());
+ assertEquals("You are a helpful assistant.\nAnswer concisely.", params.system());
+ assertEquals(8192, (int) params.maxTokens());
+ }
+
+ @Test
+ @Tag("valid")
+ public void testNonEmptyToolsMapSetsToolChoiceAuto() {
+ // Arrange
+ String modelName = "claude-3-haiku"; // TODO: Change model name if needed
+ Claude claude = new Claude(modelName, anthropicClient);
+ BaseTool dummyTool = Mockito.mock(BaseTool.class);
+ Content userContent =
+ Content.builder()
+ .role("user")
+ .parts(ImmutableList.of(Part.builder().text("Compute sum").build()))
+ .build();
+ LlmRequest llmRequest =
+ LlmRequest.builder()
+ .contents(ImmutableList.of(userContent))
+ .tools(ImmutableMap.of("dummy", dummyTool))
+ .build();
+ Message mockMessage = Mockito.mock(Message.class);
+ when(mockMessage.content()).thenReturn(ImmutableList.of());
+ when(anthropicClient.messages().create(any(MessageCreateParams.class))).thenReturn(mockMessage);
+ // Act
+ Flowable flowable = claude.generateContent(llmRequest, false);
+ TestSubscriber ts = flowable.test();
+ // Assert Flowable behavior
+ ts.assertComplete();
+ ts.assertValueCount(1);
+ assertNotNull(ts.values().get(0));
+ // Verify params sent
+ ArgumentCaptor paramsCaptor =
+ ArgumentCaptor.forClass(MessageCreateParams.class);
+ verify(anthropicClient.messages(), times(1)).create(paramsCaptor.capture());
+ MessageCreateParams params = paramsCaptor.getValue();
+ assertEquals(claude.model(), params.model());
+ assertEquals(8192, (int) params.maxTokens());
+ Optional toolChoiceOpt = params.toolChoice();
+ assertTrue(toolChoiceOpt.isPresent());
+ Optional> toolsListOpt = params.tools();
+ assertTrue(toolsListOpt.isEmpty() || toolsListOpt.get().isEmpty());
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testModelOverrideFromRequest() {
+ // Arrange
+ String defaultModelName = "claude-3-opus";
+ Claude claude = new Claude(defaultModelName, anthropicClient);
+ String overrideModel = "override-model";
+ Content userContent =
+ Content.builder()
+ .role("user")
+ .parts(ImmutableList.of(Part.builder().text("Ping").build()))
+ .build();
+ // Mock LlmRequest to provide model override
+ LlmRequest llmRequestWithModel = Mockito.mock(LlmRequest.class);
+ when(llmRequestWithModel.contents()).thenReturn(ImmutableList.of(userContent));
+ when(llmRequestWithModel.model()).thenReturn(Optional.of(overrideModel));
+ when(llmRequestWithModel.config()).thenReturn(Optional.empty());
+ when(llmRequestWithModel.tools()).thenReturn(ImmutableMap.of());
+ Message mockMessage = Mockito.mock(Message.class);
+ when(mockMessage.content()).thenReturn(ImmutableList.of());
+ when(anthropicClient.messages().create(any(MessageCreateParams.class))).thenReturn(mockMessage);
+ // Act
+ Flowable flowable = claude.generateContent(llmRequestWithModel, false);
+ TestSubscriber ts = flowable.test();
+ // Assert
+ ts.assertComplete();
+ ts.assertValueCount(1);
+ ArgumentCaptor paramsCaptor =
+ ArgumentCaptor.forClass(MessageCreateParams.class);
+ verify(anthropicClient.messages(), times(1)).create(paramsCaptor.capture());
+ MessageCreateParams params = paramsCaptor.getValue();
+ assertEquals(overrideModel, params.model());
+ assertEquals(8192, (int) params.maxTokens());
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testCustomMaxTokensFromConstructor() {
+ // Arrange
+ int customMaxTokens = 1024;
+ Claude claude = new Claude("claude-3-haiku", anthropicClient, customMaxTokens);
+ Content userContent =
+ Content.builder()
+ .role("user")
+ .parts(ImmutableList.of(Part.builder().text("Short response please").build()))
+ .build();
+ LlmRequest llmRequest = LlmRequest.builder().contents(ImmutableList.of(userContent)).build();
+ Message mockMessage = Mockito.mock(Message.class);
+ when(mockMessage.content()).thenReturn(ImmutableList.of());
+ when(anthropicClient.messages().create(any(MessageCreateParams.class))).thenReturn(mockMessage);
+ // Act
+ Flowable flowable = claude.generateContent(llmRequest, false);
+ TestSubscriber ts = flowable.test();
+ // Assert
+ ts.assertComplete();
+ ts.assertValueCount(1);
+ ArgumentCaptor paramsCaptor =
+ ArgumentCaptor.forClass(MessageCreateParams.class);
+ verify(anthropicClient.messages(), times(1)).create(paramsCaptor.capture());
+ MessageCreateParams params = paramsCaptor.getValue();
+ assertEquals(customMaxTokens, (int) params.maxTokens());
+ }
+
+ @Test
+ @Tag("invalid")
+ public void testUnsupportedPartThrowsException() {
+ // Arrange
+ Claude claude = new Claude("claude-3-opus", anthropicClient);
+ // Create a Part without text, functionCall or functionResponse to trigger
+ // UnsupportedOperationException
+ Part unsupportedPart = Part.builder().build();
+ Content userContent =
+ Content.builder().role("user").parts(ImmutableList.of(unsupportedPart)).build();
+ LlmRequest llmRequest = LlmRequest.builder().contents(ImmutableList.of(userContent)).build();
+ // Act + Assert
+ assertThrows(
+ UnsupportedOperationException.class,
+ () -> {
+ claude.generateContent(llmRequest, false);
+ });
+ }
+
+ @Test
+ @Tag("valid")
+ public void testAssistantRoleMapsToAssistant() {
+ // Arrange
+ Claude claude = new Claude("claude-3-opus", anthropicClient);
+ Content assistantContent =
+ Content.builder()
+ .role("assistant")
+ .parts(ImmutableList.of(Part.builder().text("Assistant message").build()))
+ .build();
+ LlmRequest llmRequest =
+ LlmRequest.builder().contents(ImmutableList.of(assistantContent)).build();
+ Message mockMessage = Mockito.mock(Message.class);
+ when(mockMessage.content()).thenReturn(ImmutableList.of());
+ when(anthropicClient.messages().create(any(MessageCreateParams.class))).thenReturn(mockMessage);
+ // Act
+ Flowable flowable = claude.generateContent(llmRequest, false);
+ TestSubscriber ts = flowable.test();
+ // Assert
+ ts.assertComplete();
+ ts.assertValueCount(1);
+ ArgumentCaptor paramsCaptor =
+ ArgumentCaptor.forClass(MessageCreateParams.class);
+ verify(anthropicClient.messages(), times(1)).create(paramsCaptor.capture());
+ MessageCreateParams params = paramsCaptor.getValue();
+ List sentMessages = params.messages();
+ assertNotNull(sentMessages);
+ assertEquals(1, (int) sentMessages.size());
+ assertEquals(Role.ASSISTANT, sentMessages.get(0).role());
+ assertNotNull(sentMessages.get(0).content());
+ }
+}
diff --git a/pom.xml b/pom.xml
index 6009c7316..b21618b54 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,4 @@
-
+
-
+
4.0.0
-
com.google.adk
google-adk-parent
- 0.4.1-SNAPSHOT
+ 0.4.1-SNAPSHOT
+
pom
-
Google Agent Development Kit Maven Parent POM
https://github.com/google/adk-java
Google Agent Development Kit (ADK) for Java
-
core
dev
@@ -39,12 +35,10 @@
a2a
a2a/webservice
-
17
${java.version}
UTF-8
-
1.11.0
3.4.1
1.49.0
@@ -73,7 +67,6 @@
3.9.0
5.4.3
-
@@ -112,7 +105,6 @@
pom
import
-
com.anthropic
@@ -274,9 +266,21 @@
assertj-core
${assertj.version}
+
+ org.mockito
+ mockito-junit-jupiter
+ 5.2.0
+ test
+
+
+
+ io.spring.javaformat
+ spring-javaformat-formatter
+ 0.0.40
+
+
-
@@ -324,8 +328,7 @@
plain
-
+
**/*Test.java
@@ -469,6 +472,36 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.2.5
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+ 3.2.5
+
+ testReport
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 2.1
+
+ testReport
+
+
+
+
+ io.spring.javaformat
+ spring-javaformat-maven-plugin
+ 0.0.40
+
+
@@ -528,7 +561,6 @@
-
The Apache License, Version 2.0
@@ -558,4 +590,19 @@
https://central.sonatype.com/repository/maven-snapshots/
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 5.2.0
+ test
+
+
+
+ io.spring.javaformat
+ spring-javaformat-formatter
+ 0.0.40
+
+
+
\ No newline at end of file