Ich bin süchtig danach, Testcode für Klassen zu schreiben, die "Context" im Konstruktor empfangen und "Context.openFileInput" und "Context.openFileOutput" verwenden, also schreibe ich ihn auf.
BooleanRepository.java
public class BooleanRepository {
static final String FILE_NAME = "BOOLEAN.txt";
@NonNull private final Context context;
public BooleanRepository(@NonNull Context context) { this.context = context; }
public boolean load() throws IOException {
try (final InputStream is = context.openFileInput(FILE_NAME);
final InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
final BufferedReader reader = new BufferedReader(isr)) {
return Boolean.valueOf(reader.readLine());
}
}
public void save(boolean bool) throws IOException {
try (final OutputStream os = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
final OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8);
final PrintWriter writer = new PrintWriter(osw)) {
writer.append(bool);
}
}
}
Mit * Robolectric * können auch Android-abhängige Tests auf der JVM ausgeführt werden.
build.gradle
android {
compileSdkVersion 28
...
testOptions {
unitTests {
includeAndroidResources = true
}
}
}
dependencies {
testImplementation 'androidx.test:core:1.2.0'
testImplementation 'com.google.truth:truth:0.45'
}
BooleanRepositorySpec.java
@RunWith(RobolectricTestRunner.class)
public class MemoRepositorySpec {
private static final boolean INPUT_BOOL = true;
private static final String INPUT_STRING = String.valueOf(INPUT_BOOL);
private BooleanRepository booleanRepository;
private Context context;
@Before
public void setUp() {
this.context = ApplicationProvider.getApplicationContext();
this.booleanRepository = new BooleanRepository(context);
}
@Test
public void load() throws Exception {
final File file = new File(context.getFilesDir(), BooleanRepository.FILE_NAME);
try (final Writer fileWriter = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) {
fileWriter.write(INPUT_STRING);
}
final boolean output = booleanRepository.load();
assertThat(output).isEqualTo(INPUT_BOOL);
}
@Test
public void save() throws Exception {
booleanRepository.save(true);
final File file = new File(context.getFilesDir(), BooleanRepository.FILE_NAME);
try (final FileInputStream fileInputStream = new FileInputStream(file)) {
final byte[] readBuffer = new byte[INPUT_STRING.length()];
fileInputStream.read(readBuffer);
assertThat(readBuffer).isEqualTo(INPUT_STRING);
}
}
}
BufferedReader
und PrintWriter
Warum verspotten Sie nicht zuerst den neuen "BufferedReader" und "PrintWriter" in der Methode mit "PowerMock"? Ich dachte. Ich wusste jedoch nicht, wie man "PowerMock" benutzt und gab auf, weil ich es nicht gut ersetzen konnte.
Context.openFileInput
und Context.openFileOutput
Was wäre, wenn wir als nächstes "Context.openFileInput" und "Context.openFileOutput" verspotten könnten, um "ByteArrayInputStream" und "ByteArrayOutputStream" zurückzugeben? Ich dachte. Die Rückgabewerte von "Context.openFileInput" und "Context.openFileOutput" sind jedoch "FileInputStream" bzw. "FileOutputStream", sodass die Rückgabewerte nicht übereinstimmen und daher nicht möglich sind.
Erstellen Sie eine Methode, die "InputStream" und "OutputStream" zurückgibt.
BooleanRepository.java
InputStream getInputStream() throws FileNotFoundException {
return context.openFileInput(FILE_NAME);
}
OutputStream getOutputStream() throws FileNotFoundException {
return context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
}
Ändern Sie die zu testende Methode, um daraus zu lesen.
BooleanRepository.java
try (final InputStream is = getInputStream();
/* ... */
try (final OutputStream os = getOutputStream();
Verspotten Sie diese Methode mit Mockito
und geben Sie ByteArrayInputStream
bzw. ByteArrayOutputStream
zurück.
Sie können das Byte-Array des Dateiinhalts an den Konstruktor für "ByteArrayInputStream" übergeben.
Für ByteArrayOutputStream
können Sie den Ausgabeinhalt mit byte [] lesen, indem Sie .toByteArray ()
ausführen.
BooleanRepositorySpec.java
public class MemoRepositorySpec {
private static final boolean INPUT_BOOL = true;
private static final byte[] INPUT_BYTES = String.valueOf(INPUT_BOOL).getBypes(StandardCharsets.UTF_8);
@Spy
private BooleanRepository booleanRepository;
private Context context;
@Before
public void setUp() {
context = mock(Context.class);
booleanRepository = new BooleanRepository(context);
MockitoAnnotations.initMocks(this);
}
@Test
public void load() throws Exception {
final ByteArrayInputStream is = new ByteArrayInputStream(INPUT_BYTES);
doReturn(is).when(booleanRepository).getInputStream();
final boolean output = booleanRepository.load();
assertThat(output).isEqualTo(INPUT_BOOL);
}
@Test
public void save() throws Exception {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
doReturn(os).when(booleanRepository).getOutputStream();
booleanRepository.save(true);
assertThat(os.toByteArray()).containsExactly(INPUT_BYTES);
}
}
Recommended Posts