Dies ist ein wenig Android spezifisch, aber es kann auf nicht-Android-Projekte anwendbar sein.Komponententestmethode, die die endgültige nicht blockierbare Klasse instanziiert
Ich habe diese Klasse, die eine FilterEntity
auf ContentValues
abbildet. FilterEntity
ist eine Datenstruktur, die ich erstellt und gesteuert, während ContentValues
ist eine letzte Klasse aus dem Android SDK, die eine RuntimeException
werfen wird, wenn es nicht verspottet wird.
public class FilterEntityToContentValuesMapper {
public ContentValues mapOrThrow(FilterEntity filter) {
final ContentValues values = new ContentValues();
values.put(FilterSchema.COLUMN_ID, filter.id().toString());
values.put(FilterSchema.COLUMN_NAME, filter.name());
// and others...
return values;
}
}
Bei der Prüfung ContentValues#put
sofort ein RuntimeException
werfen, da es sich nicht spotten, aber das Problem ist, dass es aus zwei Gründen nicht verspottet werden kann. Zuerst ist ContentValues
endgültig, zweitens wird es im Methodenkörper instanziiert.
das erste Problem zu lösen ich ein ContentValuesWrapper
gemacht, die genau die gleiche Funktionalität wie ContentValues
sondern delegiert alles zu einem echten ContentValues
Objekt zur Verfügung stellt. Für die zweite Ausgabe habe ich eine ContentValuesWrapperFactory
gemacht, die Instanzen von ContentValuesWrapper
zur Verfügung stellt. Das Endergebnis ist in etwa so:
public class FilterEntityToContentValuesMapper {
private final ContentValuesWrapperFactory contentValuesWrapperFactory;
public FilterEntityToContentValuesMapper(ContentValuesWrapperFactory contentValuesWrapperFactory) {
this.contentValuesWrapperFactory = contentValuesWrapperFactory;
}
public ContentValues mapOrThrow(FilterEntity filter) {
final ContentValuesWrapper values = contentValuesWrapperFactory.createContentValuesWrapper();
values.put(FilterSchema.COLUMN_ID, filter.id().toString());
values.put(FilterSchema.COLUMN_NAME, filter.name());
// and others...
return values;
}
}
Ich frage mich, ob es ein besserer Weg, dies zu lösen, da ich Funktionalität bin Duplizieren mit ContentValuesWrapper
.
Ich PowerMock verwenden, aber ich versuche es möglichst sparsam zu verwenden, da es Einheit Testzeit erhöht durch ~ 120ms jedes Mal wenn ich es benutze. 'ContentValues' wird sehr häufig für Datenbanktransaktionen verwendet, daher müsste ich die Testzeit mehrerer Testklassen erhöhen, indem Sie PowerMock jedes Mal verwenden, wenn' ContentValues' verwendet wird. –