Refactor: Adding unit test for `AdbServerLauncher`

This commit is contained in:
Samuel Carlsson 2016-09-10 09:13:29 +02:00
parent a01ce1bb17
commit 58a370928e
6 changed files with 177 additions and 12 deletions

View File

@ -1,32 +1,30 @@
package se.vidstige.jadb;
import java.io.IOException;
import java.util.Map;
/**
* Launches the ADB server
*/
public class AdbServerLauncher {
private Runtime runtime;
private final String executable;
private Subprocess subprocess;
public AdbServerLauncher() {
this(Runtime.getRuntime());
public AdbServerLauncher(Subprocess subprocess, Map<String, String> environment) {
this.subprocess = subprocess;
this.executable = findAdbExecutable(environment);
}
public AdbServerLauncher(Runtime runtime) {
this.runtime = runtime;
}
private String findAdbExecutable() {
String android_home = System.getenv("ANDROID_HOME");
private static String findAdbExecutable(Map<String, String> environment) {
String android_home = environment.get("ANDROID_HOME");
if (android_home == null || android_home.equals("")) {
return "adb";
}
return android_home + "/platform-tools/adb";
}
public void launch() throws IOException, InterruptedException {
Process p = runtime.exec(new String[]{findAdbExecutable(), "start-server"});
Process p = subprocess.execute(new String[]{executable, "start-server"});
p.waitFor();
int exitValue = p.exitValue();
if (exitValue != 0) throw new IOException("adb exited with exit code: " + exitValue);

View File

@ -0,0 +1,9 @@
package se.vidstige.jadb;
import java.io.IOException;
public class Subprocess {
public Process execute(String[] command) throws IOException {
return Runtime.getRuntime().exec(command);
}
}

View File

@ -0,0 +1,41 @@
package se.vidstige.jadb.test.fakes;
import java.io.InputStream;
import java.io.OutputStream;
public class FakeProcess extends Process {
private final int exitValue;
public FakeProcess(int exitValue) {
this.exitValue = exitValue;
}
@Override
public OutputStream getOutputStream() {
return null;
}
@Override
public InputStream getInputStream() {
return null;
}
@Override
public InputStream getErrorStream() {
return null;
}
@Override
public int waitFor() throws InterruptedException {
return 0;
}
@Override
public int exitValue() {
return exitValue;
}
@Override
public void destroy() {
}
}

View File

@ -0,0 +1,72 @@
package se.vidstige.jadb.test.fakes;
import se.vidstige.jadb.Subprocess;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FakeSubprocess extends Subprocess {
private List<Expectation> expectations = new ArrayList<>();
public Expectation expect(String[] command, int exitValue) {
Expectation builder = new Expectation(command, exitValue);
expectations.add(builder);
return builder;
}
private String format(String[] command) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < command.length; i++) {
if (i > 0) {
sb.append(" ");
}
sb.append(command[i]);
}
return sb.toString();
}
@Override
public Process execute(String[] command) throws IOException {
List<Expectation> toRemove = new ArrayList<>();
for (Expectation e : expectations) {
if (e.matches(command)) {
toRemove.add(e);
}
}
expectations.removeAll(toRemove);
if (toRemove.size() == 1) {
return new FakeProcess(toRemove.get(0).getExitValue());
}
throw new AssertionError("Unexpected command: " + format(command));
}
public void verifyExpectations() {
if (expectations.size() > 0) {
throw new AssertionError("Subprocess never called: " + format(expectations.get(0).getCommand()));
}
}
private class Expectation {
private final String[] command;
private final int exitValue;
public Expectation(String[] command, int exitValue) {
this.command = command;
this.exitValue = exitValue;
}
public boolean matches(String[] command) {
return Arrays.equals(command, this.command);
}
public int getExitValue() {
return exitValue;
}
public String[] getCommand() {
return command;
}
}
}

View File

@ -23,7 +23,7 @@ public class RealDeviceTestCases {
@BeforeClass
public static void tryToStartAdbServer() {
try {
new AdbServerLauncher().launch();
new AdbServerLauncher(new Subprocess(), System.getenv()).launch();
} catch (IOException e) {
System.out.println("Could not start adb-server");
} catch (InterruptedException e) {

View File

@ -0,0 +1,45 @@
package se.vidstige.jadb.test.unit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import se.vidstige.jadb.AdbServerLauncher;
import se.vidstige.jadb.test.fakes.FakeSubprocess;
import java.io.IOException;
import java.util.*;
public class AdbServerLauncherFixture {
private FakeSubprocess subprocess;
private Map<String, String> environment = new HashMap<>();
@Before
public void setUp() {
subprocess = new FakeSubprocess();
}
@After
public void tearDown() {
subprocess.verifyExpectations();
}
@Test
public void testStartServer() throws Exception {
subprocess.expect(new String[]{"/abc/platform-tools/adb", "start-server"}, 0);
Map<String, String> environment = new HashMap<>();
environment.put("ANDROID_HOME", "/abc");
new AdbServerLauncher(subprocess, environment).launch();
}
@Test
public void testStartServerWithoutANDROID_HOME() throws Exception {
subprocess.expect(new String[]{"adb", "start-server"}, 0);
new AdbServerLauncher(subprocess, environment).launch();
}
@Test(expected=IOException.class)
public void testStartServerFails() throws Exception {
subprocess.expect(new String[]{"adb", "start-server"}, -1);
new AdbServerLauncher(subprocess, environment).launch();
}
}