I made a custom ArrayAdapter and added a custom filter. The implementation side is fine, there are other questions about this on SO. My question is about testing. I cannot test the custom filter, being an inner that needs access to the owning ArrayAdapter subclass. So I'm testing the custom ArrayAdapter itself :
@RunWith(AndroidJUnit4::class)
@SmallTest
class EquipmentTypeAdapterTest {
@Test
@UiThreadTest
fun filtersBasedOnCategory() {
val typesForCategory = mapOf(
"Category1" to listOf("Type 1", "Type 2"),
"Category2" to listOf("Type 3")
)
val adapter = EquipmentTypeAdapter(
InstrumentationRegistry.getInstrumentation().context,
typesForCategory
)
adapter.filter.filter("Category 2") // asynchronous call
assertEquals(adapter.count, 1)
assertEquals(adapter.getItem(0), "Type 3")
}
}
My filter is a subclass of android.widget.Filter. The implementation of the filter method is inherited and the processing of the filter is asynchronous. See the implementation here :
public abstract class Filter {
// ...
/**
* <p>Starts an asynchronous filtering operation. Calling this method
* cancels all previous non-executed filtering requests and posts a new
* filtering request that will be executed later.</p>
*
* <p>Upon completion, the listener is notified.</p>
*
* @param constraint the constraint used to filter the data
* @param listener a listener notified upon completion of the operation
*
* @see #filter(CharSequence)
* @see #performFiltering(CharSequence)
* @see #publishResults(CharSequence, android.widget.Filter.FilterResults)
*/
public final void filter(CharSequence constraint, FilterListener listener) {
synchronized (mLock) {
if (mThreadHandler == null) {
HandlerThread thread = new HandlerThread(
THREAD_NAME, android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mThreadHandler = new RequestHandler(thread.getLooper());
}
final long delay = (mDelayer == null) ? 0 : mDelayer.getPostingDelay(constraint);
Message message = mThreadHandler.obtainMessage(FILTER_TOKEN);
RequestArguments args = new RequestArguments();
// make sure we use an immutable copy of the constraint, so that
// it doesn't change while the filter operation is in progress
args.constraint = constraint != null ? constraint.toString() : null;
args.listener = listener;
message.obj = args;
mThreadHandler.removeMessages(FILTER_TOKEN);
mThreadHandler.removeMessages(FINISH_TOKEN);
mThreadHandler.sendMessageDelayed(message, delay);
}
}
}
So the assertions are executed before the filter is actually executed and they fail.
I imagine I would like to delay the processing of the assertions after the filter is executed (after the publishResults method is called). And the main thread has to wait for all of to have happened before finishing. How can I do that? Or is there a differet way?
Aucun commentaire:
Enregistrer un commentaire