Skip to content

Commit eb4377c

Browse files
MCP-54 Make tests less verbose
1 parent b004fb7 commit eb4377c

20 files changed

+255
-330
lines changed

src/test/java/org/sonarsource/sonarqube/mcp/harness/SonarQubeMcpServerTestHarness.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ public MockWebServer getMockSonarQubeServer() {
110110
return mockSonarQubeServer;
111111
}
112112

113-
public McpSyncClient newClient() {
113+
public SonarQubeMcpTestClient newClient() {
114114
return newClient(Map.of());
115115
}
116116

117-
public McpSyncClient newClient(Map<String, String> overriddenEnv) {
117+
public SonarQubeMcpTestClient newClient(Map<String, String> overriddenEnv) {
118118
if (!overriddenEnv.containsKey("SONARQUBE_ORG")) {
119119
mockSonarQubeServer.stubFor(get(SystemApi.STATUS_PATH)
120120
.willReturn(aResponse().withResponseBody(
@@ -156,7 +156,7 @@ public McpSyncClient newClient(Map<String, String> overriddenEnv) {
156156
client.initialize();
157157
this.clients.add(client);
158158
this.servers.add(server);
159-
return client;
159+
return new SonarQubeMcpTestClient(client);
160160
}
161161

162162
private static void printLogs(McpSchema.LoggingMessageNotification notification) {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* SonarQube MCP Server
3+
* Copyright (C) 2025 SonarSource
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the Sonar Source-Available License for more details.
13+
*
14+
* You should have received a copy of the Sonar Source-Available License
15+
* along with this program; if not, see https://sonarsource.com/license/ssal/
16+
*/
17+
package org.sonarsource.sonarqube.mcp.harness;
18+
19+
import io.modelcontextprotocol.client.McpSyncClient;
20+
import io.modelcontextprotocol.spec.McpSchema;
21+
import java.util.Map;
22+
23+
public class SonarQubeMcpTestClient {
24+
private final McpSyncClient mcpSyncClient;
25+
26+
public SonarQubeMcpTestClient(McpSyncClient mcpSyncClient) {
27+
this.mcpSyncClient = mcpSyncClient;
28+
}
29+
30+
public McpSchema.CallToolResult callTool(String toolName) {
31+
return callTool(toolName, Map.of());
32+
}
33+
34+
public McpSchema.CallToolResult callTool(String toolName, Map<String, Object> arguments) {
35+
return mcpSyncClient.callTool(new McpSchema.CallToolRequest(toolName, arguments));
36+
}
37+
38+
}

src/test/java/org/sonarsource/sonarqube/mcp/tools/analysis/AnalysisToolTests.java

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,9 @@ class MissingPrerequisite {
3939
void it_should_return_an_error_if_codeSnippet_is_missing(SonarQubeMcpServerTestHarness harness) {
4040
var mcpClient = harness.newClient();
4141

42-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
42+
var result = mcpClient.callTool(
4343
AnalysisTool.TOOL_NAME,
44-
Map.of(
45-
AnalysisTool.LANGUAGE_PROPERTY, "")));
44+
Map.of(AnalysisTool.LANGUAGE_PROPERTY, ""));
4645

4746
assertThat(result)
4847
.isEqualTo(new McpSchema.CallToolResult("An error occurred during the tool execution: Missing required argument: codeSnippet", true));
@@ -57,11 +56,11 @@ void it_should_find_no_issues_in_an_empty_file(SonarQubeMcpServerTestHarness har
5756
mockServerRules(harness, null, List.of("php:S1135"));
5857
var mcpClient = harness.newClient();
5958

60-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
59+
var result = mcpClient.callTool(
6160
AnalysisTool.TOOL_NAME,
6261
Map.of(
6362
AnalysisTool.SNIPPET_PROPERTY, "",
64-
AnalysisTool.LANGUAGE_PROPERTY, "")));
63+
AnalysisTool.LANGUAGE_PROPERTY, ""));
6564

6665
assertThat(result)
6766
.isEqualTo(new McpSchema.CallToolResult("No Sonar issues found in the code snippet.", false));
@@ -72,13 +71,13 @@ void it_should_find_an_issues_in_a_php_file_when_rule_enabled_in_default_quality
7271
mockServerRules(harness, null, List.of("php:S1135"));
7372
var mcpClient = harness.newClient();
7473

75-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
74+
var result = mcpClient.callTool(
7675
AnalysisTool.TOOL_NAME,
7776
Map.of(
7877
AnalysisTool.SNIPPET_PROPERTY, """
7978
// TODO just do it
8079
""",
81-
AnalysisTool.LANGUAGE_PROPERTY, "php")));
80+
AnalysisTool.LANGUAGE_PROPERTY, "php"));
8281

8382
assertThat(result)
8483
.isEqualTo(new McpSchema.CallToolResult("""
@@ -98,14 +97,14 @@ void it_should_find_an_issues_in_a_php_file_when_rule_enabled_in_project_quality
9897
mockServerRules(harness, "projectKey", List.of("php:S1135"));
9998
var mcpClient = harness.newClient();
10099

101-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
100+
var result = mcpClient.callTool(
102101
AnalysisTool.TOOL_NAME,
103102
Map.of(
104103
AnalysisTool.PROJECT_KEY_PROPERTY, "projectKey",
105104
AnalysisTool.SNIPPET_PROPERTY, """
106105
// TODO just do it
107106
""",
108-
AnalysisTool.LANGUAGE_PROPERTY, "php")));
107+
AnalysisTool.LANGUAGE_PROPERTY, "php"));
109108

110109
assertThat(result)
111110
.isEqualTo(new McpSchema.CallToolResult("""
@@ -125,13 +124,13 @@ void it_should_find_no_issues_if_rule_is_not_active(SonarQubeMcpServerTestHarnes
125124
mockServerRules(harness, null, List.of());
126125
var mcpClient = harness.newClient();
127126

128-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
127+
var result = mcpClient.callTool(
129128
AnalysisTool.TOOL_NAME,
130129
Map.of(
131130
AnalysisTool.SNIPPET_PROPERTY, """
132131
// TODO just do it
133132
""",
134-
AnalysisTool.LANGUAGE_PROPERTY, "php")));
133+
AnalysisTool.LANGUAGE_PROPERTY, "php"));
135134

136135
assertThat(result)
137136
.isEqualTo(new McpSchema.CallToolResult("No Sonar issues found in the code snippet.", false));
@@ -166,13 +165,13 @@ private static void mockRules(SonarQubeMcpServerTestHarness harness, String qual
166165
"""::formatted).collect(Collectors.joining(","));
167166

168167
harness.getMockSonarQubeServer().stubFor(get(RulesApi.SEARCH_PATH + "?qprofile=" + qualityProfileKey + "&activation=true&f=templateKey%2Cactives&p=1").willReturn(okJson(
169-
"""
170-
{
171-
"actives": {
172-
%s
168+
"""
169+
{
170+
"actives": {
171+
%s
172+
}
173173
}
174-
}
175-
""".formatted(rulesPayload))));
174+
""".formatted(rulesPayload))));
176175
}
177176

178177
}

src/test/java/org/sonarsource/sonarqube/mcp/tools/issues/ChangeIssuesStatusToolTests.java

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ class MissingPrerequisite {
3737
void it_should_return_an_error_if_the_key_parameter_is_missing(SonarQubeMcpServerTestHarness harness) {
3838
var mcpClient = harness.newClient();
3939

40-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
40+
var result = mcpClient.callTool(
4141
ChangeIssueStatusTool.TOOL_NAME,
42-
Map.of("status", new String[]{"accept"})));
42+
Map.of("status", new String[] {"accept"}));
4343

4444
assertThat(result)
4545
.isEqualTo(new McpSchema.CallToolResult("An error occurred during the tool execution: Missing required argument: key", true));
@@ -49,9 +49,9 @@ void it_should_return_an_error_if_the_key_parameter_is_missing(SonarQubeMcpServe
4949
void it_should_return_an_error_if_the_status_parameter_is_missing(SonarQubeMcpServerTestHarness harness) {
5050
var mcpClient = harness.newClient();
5151

52-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
52+
var result = mcpClient.callTool(
5353
ChangeIssueStatusTool.TOOL_NAME,
54-
Map.of("key", "k")));
54+
Map.of("key", "k"));
5555

5656
assertThat(result)
5757
.isEqualTo(new McpSchema.CallToolResult("An error occurred during the tool execution: Missing required argument: status", true));
@@ -61,9 +61,11 @@ void it_should_return_an_error_if_the_status_parameter_is_missing(SonarQubeMcpSe
6161
void it_should_return_an_error_if_the_status_parameter_is_unknown(SonarQubeMcpServerTestHarness harness) {
6262
var mcpClient = harness.newClient();
6363

64-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
64+
var result = mcpClient.callTool(
6565
ChangeIssueStatusTool.TOOL_NAME,
66-
Map.of("key", "k", "status", new String[]{"yolo"})));
66+
Map.of(
67+
"key", "k",
68+
"status", new String[] {"yolo"}));
6769

6870
assertThat(result)
6971
.isEqualTo(new McpSchema.CallToolResult("Status is unknown: yolo", true));
@@ -78,13 +80,12 @@ class WithSonarCloudServer {
7880
void it_should_return_an_error_if_the_request_fails_due_to_token_permission(SonarQubeMcpServerTestHarness harness) {
7981
harness.getMockSonarQubeServer().stubFor(post("/api/issues/do_transition").willReturn(aResponse().withStatus(403)));
8082
var mcpClient = harness.newClient(Map.of(
81-
"SONARQUBE_ORG", "org"
82-
));
83+
"SONARQUBE_ORG", "org"));
8384

84-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
85+
var result = mcpClient.callTool(
8586
ChangeIssueStatusTool.TOOL_NAME,
8687
Map.of("key", "k",
87-
"status", new String[]{"accept"})));
88+
"status", new String[] {"accept"}));
8889

8990
assertThat(result)
9091
.isEqualTo(new McpSchema.CallToolResult("An error occurred during the tool execution: SonarQube answered with Forbidden", true));
@@ -94,13 +95,12 @@ void it_should_return_an_error_if_the_request_fails_due_to_token_permission(Sona
9495
void it_should_change_the_status_to_accept(SonarQubeMcpServerTestHarness harness) {
9596
harness.getMockSonarQubeServer().stubFor(post("/api/issues/do_transition").willReturn(ok()));
9697
var mcpClient = harness.newClient(Map.of(
97-
"SONARQUBE_ORG", "org"
98-
));
98+
"SONARQUBE_ORG", "org"));
9999

100-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
100+
var result = mcpClient.callTool(
101101
ChangeIssueStatusTool.TOOL_NAME,
102102
Map.of("key", "k",
103-
"status", new String[]{"accept"})));
103+
"status", new String[] {"accept"}));
104104

105105
assertThat(result).isEqualTo(new McpSchema.CallToolResult("The issue status was successfully changed.", false));
106106
assertThat(harness.getMockSonarQubeServer().getReceivedRequests())
@@ -111,13 +111,12 @@ void it_should_change_the_status_to_accept(SonarQubeMcpServerTestHarness harness
111111
void it_should_change_the_status_to_false_positive(SonarQubeMcpServerTestHarness harness) {
112112
harness.getMockSonarQubeServer().stubFor(post("/api/issues/do_transition").willReturn(ok()));
113113
var mcpClient = harness.newClient(Map.of(
114-
"SONARQUBE_ORG", "org"
115-
));
114+
"SONARQUBE_ORG", "org"));
116115

117-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
116+
var result = mcpClient.callTool(
118117
ChangeIssueStatusTool.TOOL_NAME,
119118
Map.of("key", "k",
120-
"status", new String[]{"falsepositive"})));
119+
"status", new String[] {"falsepositive"}));
121120

122121
assertThat(result).isEqualTo(new McpSchema.CallToolResult("The issue status was successfully changed.", false));
123122
assertThat(harness.getMockSonarQubeServer().getReceivedRequests())
@@ -128,13 +127,12 @@ void it_should_change_the_status_to_false_positive(SonarQubeMcpServerTestHarness
128127
void it_should_reopen_the_issue(SonarQubeMcpServerTestHarness harness) {
129128
harness.getMockSonarQubeServer().stubFor(post("/api/issues/do_transition").willReturn(ok()));
130129
var mcpClient = harness.newClient(Map.of(
131-
"SONARQUBE_ORG", "org"
132-
));
130+
"SONARQUBE_ORG", "org"));
133131

134-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
132+
var result = mcpClient.callTool(
135133
ChangeIssueStatusTool.TOOL_NAME,
136134
Map.of("key", "k",
137-
"status", new String[]{"reopen"})));
135+
"status", new String[] {"reopen"}));
138136

139137
assertThat(result).isEqualTo(new McpSchema.CallToolResult("The issue status was successfully changed.", false));
140138
assertThat(harness.getMockSonarQubeServer().getReceivedRequests())

src/test/java/org/sonarsource/sonarqube/mcp/tools/issues/SearchIssuesToolTests.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@ void it_should_return_an_error_if_the_request_fails_due_to_token_permission(Sona
4242
"SONARQUBE_ORG", "org"
4343
));
4444

45-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
46-
SearchIssuesTool.TOOL_NAME,
47-
Map.of()));
45+
var result = mcpClient.callTool(SearchIssuesTool.TOOL_NAME);
4846

4947
assertThat(result)
5048
.isEqualTo(new McpSchema.CallToolResult("An error occurred during the tool execution: SonarQube answered with Forbidden", true));
@@ -75,9 +73,9 @@ void it_should_fetch_issues_for_specific_projects(SonarQubeMcpServerTestHarness
7573
"SONARQUBE_ORG", "org"
7674
));
7775

78-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
76+
var result = mcpClient.callTool(
7977
SearchIssuesTool.TOOL_NAME,
80-
Map.of(SearchIssuesTool.PROJECTS_PROPERTY, new String[]{"project1", "project2"})));
78+
Map.of(SearchIssuesTool.PROJECTS_PROPERTY, new String[]{"project1", "project2"}));
8179

8280
assertThat(result)
8381
.isEqualTo(new McpSchema.CallToolResult("""
@@ -97,9 +95,7 @@ void it_should_return_an_error_if_the_request_fails_due_to_token_permission(Sona
9795
harness.getMockSonarQubeServer().stubFor(get(IssuesApi.SEARCH_PATH).willReturn(aResponse().withStatus(403)));
9896
var mcpClient = harness.newClient();
9997

100-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
101-
SearchIssuesTool.TOOL_NAME,
102-
Map.of()));
98+
var result = mcpClient.callTool(SearchIssuesTool.TOOL_NAME);
10399

104100
assertThat(result)
105101
.isEqualTo(new McpSchema.CallToolResult("An error occurred during the tool execution: SonarQube answered with Forbidden", true));
@@ -128,9 +124,9 @@ void it_should_fetch_issues_for_specific_projects(SonarQubeMcpServerTestHarness
128124
)));
129125
var mcpClient = harness.newClient();
130126

131-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
127+
var result = mcpClient.callTool(
132128
SearchIssuesTool.TOOL_NAME,
133-
Map.of(SearchIssuesTool.PROJECTS_PROPERTY, new String[]{"project1", "project2"})));
129+
Map.of(SearchIssuesTool.PROJECTS_PROPERTY, new String[]{"project1", "project2"}));
134130

135131
assertThat(result)
136132
.isEqualTo(new McpSchema.CallToolResult("""
@@ -180,9 +176,9 @@ void it_should_return_issues_and_files_from_a_pull_request(SonarQubeMcpServerTes
180176
)));
181177
var mcpClient = harness.newClient();
182178

183-
var result = mcpClient.callTool(new McpSchema.CallToolRequest(
179+
var result = mcpClient.callTool(
184180
SearchIssuesTool.TOOL_NAME,
185-
Map.of("pullRequestId", "1")));
181+
Map.of("pullRequestId", "1"));
186182

187183
assertThat(result)
188184
.isEqualTo(new McpSchema.CallToolResult("""

0 commit comments

Comments
 (0)