Skip to content

Commit dc3c033

Browse files
authored
Replace mockito in GitCommandsExecutorTest (jenkinsci#1245)
Use real objects instead of mock objects. Use JUnit 4.13 assertThrows so that try / catch is not needed for exception testing.
1 parent 5e76640 commit dc3c033

File tree

1 file changed

+111
-68
lines changed

1 file changed

+111
-68
lines changed

src/test/java/org/jenkinsci/plugins/gitclient/cgit/GitCommandsExecutorTest.java

Lines changed: 111 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@
22

33
import static java.util.Arrays.asList;
44
import static org.hamcrest.MatcherAssert.assertThat;
5+
import static org.hamcrest.Matchers.emptyString;
56
import static org.hamcrest.Matchers.instanceOf;
67
import static org.hamcrest.Matchers.is;
78
import static org.hamcrest.Matchers.lessThan;
9+
import static org.hamcrest.Matchers.nullValue;
810
import static org.hamcrest.Matchers.theInstance;
911
import static org.junit.Assert.assertThrows;
12+
import static org.junit.Assert.assertTrue;
1013
import static org.junit.Assert.fail;
11-
import static org.mockito.Mockito.mock;
12-
import static org.mockito.Mockito.verify;
13-
import static org.mockito.Mockito.verifyNoInteractions;
14-
import static org.mockito.Mockito.when;
1514

1615
import hudson.model.TaskListener;
1716
import hudson.plugins.git.GitException;
17+
import hudson.util.StreamTaskListener;
18+
import java.io.ByteArrayOutputStream;
1819
import java.io.PrintStream;
20+
import java.nio.charset.StandardCharsets;
1921
import java.util.ArrayList;
2022
import java.util.Collections;
2123
import java.util.List;
@@ -32,15 +34,17 @@ public class GitCommandsExecutorTest {
3234

3335
private final int threads;
3436
private final TaskListener listener;
37+
private final ByteArrayOutputStream logStream;
3538

3639
public GitCommandsExecutorTest(int threads) {
3740
this.threads = threads;
38-
this.listener = mockTaskListener();
41+
this.logStream = new ByteArrayOutputStream();
42+
this.listener = new StreamTaskListener(new PrintStream(logStream), StandardCharsets.UTF_8);
3943
}
4044

4145
@After
4246
public void verifyCorrectExecutorServiceShutdown() {
43-
verifyNoInteractions(listener);
47+
loggedNoOutput();
4448
}
4549

4650
@Parameters(name = "threads={0}")
@@ -58,7 +62,7 @@ public void allCommandsSucceed() throws Exception {
5862
new GitCommandsExecutor(threads, listener).invokeAll(commands);
5963

6064
for (Callable<String> command : commands) {
61-
verify(command).call();
65+
wasCalled(command);
6266
}
6367
}
6468

@@ -69,14 +73,11 @@ public void allCommandsFail() throws Exception {
6973
commands.add(erroneousCommand(new RuntimeException("some error")));
7074
}
7175

72-
try {
76+
Exception e = assertThrows(GitException.class, () -> {
7377
new GitCommandsExecutor(threads, listener).invokeAll(commands);
74-
fail("Expected an exception but none was thrown");
75-
} catch (Exception e) {
76-
assertThat(e, instanceOf(GitException.class));
77-
assertThat(e.getMessage(), is("java.lang.RuntimeException: some error"));
78-
assertThat(e.getCause(), instanceOf(RuntimeException.class));
79-
}
78+
});
79+
assertThat(e.getMessage(), is("java.lang.RuntimeException: some error"));
80+
assertThat(e.getCause(), instanceOf(RuntimeException.class));
8081
}
8182

8283
@Test
@@ -88,21 +89,16 @@ public void firstCommandFails() throws Exception {
8889
successfulCommand("some value", commandExecutionTime));
8990

9091
long executionStartMillis = System.currentTimeMillis();
91-
try {
92+
Exception e = assertThrows(GitException.class, () -> {
9293
new GitCommandsExecutor(threads, listener).invokeAll(commands);
93-
fail("Expected an exception but none was thrown");
94-
} catch (Exception e) {
95-
assertThat(e, instanceOf(GitException.class));
96-
assertThat(e.getMessage(), is("java.lang.RuntimeException: some error"));
97-
assertThat(e.getCause(), instanceOf(RuntimeException.class));
98-
}
94+
});
95+
assertThat(e.getMessage(), is("java.lang.RuntimeException: some error"));
96+
assertThat(e.getCause(), instanceOf(RuntimeException.class));
9997
long executionStopMillis = System.currentTimeMillis();
10098

10199
for (Callable<String> command : commands) {
102100
if (commands.indexOf(command) < threads) {
103-
verify(command).call();
104-
} else {
105-
verifyNoInteractions(command);
101+
wasCalled(command);
106102
}
107103
}
108104
assertThat(executionStopMillis - executionStartMillis, is(lessThan(commandExecutionTime)));
@@ -115,17 +111,14 @@ public void lastCommandFails() throws Exception {
115111
successfulCommand("some value"),
116112
erroneousCommand(new RuntimeException("some error")));
117113

118-
try {
114+
Exception e = assertThrows(GitException.class, () -> {
119115
new GitCommandsExecutor(threads, listener).invokeAll(commands);
120-
fail("Expected an exception but none was thrown");
121-
} catch (Exception e) {
122-
assertThat(e, instanceOf(GitException.class));
123-
assertThat(e.getMessage(), is("java.lang.RuntimeException: some error"));
124-
assertThat(e.getCause(), instanceOf(RuntimeException.class));
125-
}
116+
});
117+
assertThat(e.getMessage(), is("java.lang.RuntimeException: some error"));
118+
assertThat(e.getCause(), instanceOf(RuntimeException.class));
126119

127120
for (Callable<String> command : commands) {
128-
verify(command).call();
121+
wasCalled(command);
129122
}
130123
}
131124

@@ -139,7 +132,7 @@ public void moreCommandsThanThreads() throws Exception {
139132
new GitCommandsExecutor(threads, listener).invokeAll(commands);
140133

141134
for (Callable<String> command : commands) {
142-
verify(command).call();
135+
wasCalled(command);
143136
}
144137
}
145138

@@ -153,7 +146,7 @@ public void lessCommandsThanThreads() throws Exception {
153146
new GitCommandsExecutor(threads, listener).invokeAll(commands);
154147

155148
for (Callable<String> command : commands) {
156-
verify(command).call();
149+
wasCalled(command);
157150
}
158151
}
159152

@@ -185,9 +178,9 @@ public void callerThreadWasInterrupted() throws Exception {
185178

186179
for (Callable<String> command : commands) {
187180
if (commands.indexOf(command) < threads) {
188-
verify(command).call();
181+
wasCalled(command);
189182
} else {
190-
verifyNoInteractions(command);
183+
loggedNoOutput();
191184
}
192185
}
193186
assertThat(callerStopMillis - callerStartMillis, is(lessThan(commandExecutionTime)));
@@ -198,63 +191,113 @@ public void callerThreadWasInterrupted() throws Exception {
198191
public void commandWasInterrupted() throws Exception {
199192
Exception commandException = new InterruptedException("some interrupt");
200193
List<Callable<String>> commands = Collections.singletonList(erroneousCommand(commandException));
201-
assertThrows(InterruptedException.class, () -> new GitCommandsExecutor(threads, listener).invokeAll(commands));
194+
Exception e = assertThrows(
195+
InterruptedException.class, () -> new GitCommandsExecutor(threads, listener).invokeAll(commands));
196+
assertThat(e.getMessage(), is(nullValue()));
197+
if (threads == 1) {
198+
assertThat(e.getCause(), is(nullValue()));
199+
} else {
200+
assertThat(e.getCause(), is(theInstance(commandException)));
201+
}
202202
}
203203

204204
@Test
205205
public void commandHadGitProblem() throws Exception {
206206
Exception commandException = new GitException("some error");
207207
List<Callable<String>> commands = Collections.singletonList(erroneousCommand(commandException));
208208

209-
try {
209+
Exception e = assertThrows(GitException.class, () -> {
210210
new GitCommandsExecutor(threads, listener).invokeAll(commands);
211-
fail("Expected an exception but none was thrown");
212-
} catch (Exception e) {
213-
assertThat(e, instanceOf(GitException.class));
214-
assertThat(e.getMessage(), is("hudson.plugins.git.GitException: some error"));
215-
assertThat(e.getCause(), is(theInstance(commandException)));
216-
}
211+
});
212+
assertThat(e.getMessage(), is("hudson.plugins.git.GitException: some error"));
213+
assertThat(e.getCause(), is(theInstance(commandException)));
217214
}
218215

219216
@Test
220217
public void commandHadUnknownProblem() throws Exception {
221218
Exception commandException = new RuntimeException("some error");
222219
List<Callable<String>> commands = Collections.singletonList(erroneousCommand(commandException));
223220

224-
try {
221+
Exception e = assertThrows(GitException.class, () -> {
225222
new GitCommandsExecutor(threads, listener).invokeAll(commands);
226-
fail("Expected an exception but none was thrown");
227-
} catch (Exception e) {
228-
assertThat(e, instanceOf(GitException.class));
229-
assertThat(e.getMessage(), is("java.lang.RuntimeException: some error"));
230-
assertThat(e.getCause(), is(theInstance(commandException)));
231-
}
232-
}
233-
234-
private TaskListener mockTaskListener() {
235-
TaskListener listener = mock(TaskListener.class);
236-
when(listener.getLogger()).thenReturn(mock(PrintStream.class));
237-
return listener;
223+
});
224+
assertThat(e.getMessage(), is("java.lang.RuntimeException: some error"));
225+
assertThat(e.getCause(), is(theInstance(commandException)));
238226
}
239227

240228
private Callable<String> successfulCommand(String value) throws Exception {
241-
Callable<String> command = mock(Callable.class);
242-
when(command.call()).thenReturn(value);
243-
return command;
229+
return new SuccessfulCommand(value);
244230
}
245231

246232
private Callable<String> successfulCommand(String value, long commandExecutionTime) throws Exception {
247-
Callable<String> command = mock(Callable.class);
248-
when(command.call()).then(invocation -> {
249-
Thread.sleep(commandExecutionTime);
233+
return new SuccessfulCommand(value, commandExecutionTime);
234+
}
235+
236+
private void loggedNoOutput() {
237+
String loggedOutput = logStream.toString();
238+
assertThat(loggedOutput, is(emptyString()));
239+
}
240+
241+
private void wasCalled(Callable<String> command) {
242+
if (command instanceof SuccessfulCommand succeeds) {
243+
assertTrue(succeeds.wasCalled());
244+
} else if (command instanceof ErroneousCommand erroneous) {
245+
assertTrue(erroneous.wasCalled());
246+
} else {
247+
fail("Unexpected command type " + command);
248+
}
249+
}
250+
251+
private class SuccessfulCommand implements Callable {
252+
253+
private final String value;
254+
private final long commandExecutionTime;
255+
private boolean called = false;
256+
257+
SuccessfulCommand(String value) {
258+
this(value, -1);
259+
}
260+
261+
SuccessfulCommand(String value, long commandExecutionTime) {
262+
this.value = value;
263+
this.commandExecutionTime = commandExecutionTime;
264+
}
265+
266+
boolean wasCalled() {
267+
return called;
268+
}
269+
270+
@Override
271+
public Object call() throws Exception {
272+
called = true;
273+
if (commandExecutionTime > 0) {
274+
Thread.sleep(commandExecutionTime);
275+
}
250276
return value;
251-
});
252-
return command;
277+
}
253278
}
254279

255280
private Callable<String> erroneousCommand(Exception exception) throws Exception {
256-
Callable<String> command = mock(Callable.class);
257-
when(command.call()).thenThrow(exception);
258-
return command;
281+
return new ErroneousCommand(exception);
282+
}
283+
284+
private class ErroneousCommand implements Callable {
285+
286+
private final Exception exception;
287+
private boolean called = false;
288+
289+
ErroneousCommand(Exception exceptionToThrow) {
290+
exception = exceptionToThrow;
291+
}
292+
293+
boolean wasCalled() {
294+
return called;
295+
}
296+
297+
@Override
298+
public Object call() throws Exception {
299+
called = true;
300+
throw exception;
301+
}
259302
}
260303
}

0 commit comments

Comments
 (0)