Je suis accro à la façon d'écrire du code de test pour les classes qui reçoivent Context
dans le constructeur et utilisent Context.openFileInput
et Context.openFileOutput
, donc je l'écrirai.
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);
}
}
}
Avec * Robolectric *, les tests dépendants d'Android peuvent également être exécutés sur la JVM.
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
et PrintWriter
Pourquoi ne pas se moquer des nouveaux BufferedReader
et PrintWriter
dans la méthode avec PowerMock
en premier? J'ai pensé.
Cependant, je ne savais pas comment utiliser PowerMock
et j'ai abandonné car je ne pouvais pas bien le remplacer.
Context.openFileInput
et Context.openFileOutput
Ensuite, que se passerait-il si nous pouvions nous moquer de Context.openFileInput
et Context.openFileOutput
pour renvoyer ByteArrayInputStream
et ByteArrayOutputStream
? J'ai pensé.
Cependant, les valeurs de retour de Context.openFileInput
et Context.openFileOutput
sont respectivement FileInputStream
et FileOutputStream
, donc les valeurs de retour ne correspondent pas, donc c'est impossible.
, ʻOutputStream
et moquez-laCréez une méthode qui renvoie ʻInputStream, ʻOutputStream
,
BooleanRepository.java
InputStream getInputStream() throws FileNotFoundException {
return context.openFileInput(FILE_NAME);
}
OutputStream getOutputStream() throws FileNotFoundException {
return context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
}
Modifiez la méthode testée pour en lire.
BooleanRepository.java
try (final InputStream is = getInputStream();
/* ... */
try (final OutputStream os = getOutputStream();
Simulez la méthode avec «Mockito» et renvoyez respectivement «ByteArrayInputStream» et «ByteArrayOutputStream».
Vous pouvez passer le tableau d'octets du contenu du fichier au constructeur pour ByteArrayInputStream
.
Pour ByteArrayOutputStream
, vous pouvez lire le contenu de sortie avec byte [] en faisant .toByteArray ()
.
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