-
Notifications
You must be signed in to change notification settings - Fork 23
Description
Adnroid Studio 3.3.
In my app I use Retrofit to do http request. Also I use MockWebServer to return stub response.
On activity when I click button I start async (call.enqueue(callback);) http request (by Retrofit 2) and wait callback method to return response. Here Espresso's test:
@RunWith(AndroidJUnit4::class)
class AddTraderActivityTest {
@get:Rule
var addTraderIntentTestRule: IntentsTestRule<AddTraderActivity> = IntentsTestRule(AddTraderActivity::class.java)
private val baseEditText = viewWithId(baseTextInputEditText)
private val quoteEditText = viewWithId(quoteTextInputEditText)
private val buttonStart = viewWithId(startButton)
@Before
fun setup() {
mockServer = MockWebServer()
mockServer.start(8081)
Debug.d(TAG, "SUCCCESS_START_MOCKWEBSRVER")
}
@Test
fun buttonStart_click_longResponse() {
// stub response
mockServer.enqueue(MockResponse()
.setResponseCode(200)
.setBody(FileUtil.getStringFromFile(context, "add_trader_success_200.json"))
.setBodyDelay(5000, TimeUnit.MILLISECONDS))
onView(withId(R.id.baseTextInputEditText))
.perform(typeText(BASE_TEST))
onView(withId(R.id.quoteTextInputEditText))
.perform(typeText(QUOTE_TEST))
onView(withId(R.id.startButton))
.perform(click())
onView(withText(R.id.containerProgressBarLayout))
.check(matches(isDisplayed()))
}
But problem is when execute perform(click()) the method check is not call until not get stub response (after 5 seconds).
But I need call method check immediately after perform(click()) method. Because I need to check is containerProgressBarLayout is isDisplayed() while not return stub response. I need to check my view DURING loading data.
So to do this I try this:
@Test
fun buttonStart_click_longResponse() {
// stub response
mockServer.enqueue(MockResponse()
.setResponseCode(200)
.setBody(FileUtil.getStringFromFile(context, "add_trader_success_200.json"))
.setBodyDelay(5000, TimeUnit.MILLISECONDS))
baseEditText.type(BASE_TEST)
quoteEditText.type(QUOTE_TEST)
buttonStart.click()
Debug.d(TAG, "AFTER_CLICK")
ConditionWatcher.waitForCondition(object : Instruction() {
override fun getDescription(): String {
return "test description"
}
override fun checkCondition(): Boolean {
Debug.d(TAG, "checkCondition")
return true
}
})
onView(withText(containerProgressBarLayout))
.check(matches(isDisplayed()))
}
But log AFTER_CLICK and method checkCondition() call AFTER 5 SECONDS.
When call click then call this production code:
TransportService.executeTraderOperation(Trader.Operation.CREATE, base.trim(), quote.trim(), new DefaultRestClientCallback<Void>() {
@Override
public void onSuccess(Response<Void> response) {
}
@Override
public void onError(ErrorResponse errorResponse) {
}
});
}
and this:
public static void executeTraderOperation(Trader.Operation traderOperation, String base, String quote, Callback<Void> callback) {
TraderMonitorRestClient traderMonitorRestClient = RestClientFactory.createRestClient(TraderMonitorRestClient.class);
String sender = BuildConfig.APPLICATION_ID + "_" + BuildConfig.VERSION_NAME;
String key = DateUtil.getDateAsString(new Date(), "mmHHddMMyyyy");
Call<Void> call = traderMonitorRestClient.executeTraderOperation(traderOperation.toString().toLowerCase(), base, quote, sender, key);
// asynchronously
call.enqueue(callback);
}
fun ViewInteraction.click(): ViewInteraction = perform(ViewActions.click())
fun viewWithId(@IdRes resId: Int): ViewInteraction {
return onView(withId(resId))
}