I am trying to write UI test for my Fragments with Espresso
and MockWebServer
. I am using OkHttp Idling Resource
to tell Espresso to wait for the API calls to complete.
But somehow, sometimes my tests are working but sometimes not, because Espresso
does its job before service request. So my recyclerView item click test fail.
I can not figure out why espresso does not wait for the API calls? Can anyone help?
Here is my test class
@MediumTest
@HiltAndroidTest
@UninstallModules(PersistenceModule::class, NetworkModule::class)
class MainFragmentTest {
@get:Rule
var hiltRule = HiltAndroidRule(this)
private val mockWebServer = MockWebServer()
@Inject
lateinit var okHttp3IdlingResource: OkHttp3IdlingResource
@Before
fun setUp() {
hiltRule.inject()
// Prepare Mock Web Server
mockWebServer.start(8080)
IdlingRegistry.getInstance().register(okHttp3IdlingResource)
}
@Test
fun mainFragmentTest(){
// Prepare Mock Web Server
mockWebServer.dispatcher = object : Dispatcher() {
override fun dispatch(request: RecordedRequest): MockResponse {
return MockResponse()
.setResponseCode(200)
.setBody(MockResponseFileReader("post_success.json").content)
}
}
val navController = mockk<NavController>(relaxed = true)
launchFragmentInHiltContainer<MainFragment> {
Navigation.setViewNavController(requireView(), navController)
}
onView(withId(R.id.rv_posts)).perform(
RecyclerViewActions.actionOnItemAtPosition<PostViewHolder>(
0,
click()
)
)
verify { navController.navigate(MainFragmentDirections.actionMainFragmentToDetailFragment().setPost(any())) }
}
@After
fun tearDown() {
mockWebServer.close()
}
}
Here is my TestNetworkModule
that holds network dependencies
@Module
@InstallIn(SingletonComponent::class)
object TestNetworkModule {
/**
* Provides [OkHttpClient] instance
*/
@Provides
@Singleton
fun provideOkHttpClient() : OkHttpClient {
return OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
}
/**
* Provides [OkHttp3IdlingResource] instance
*/
@Provides
@Singleton
fun provideIdlingResource(okHttpClient: OkHttpClient) : OkHttp3IdlingResource {
return OkHttp3IdlingResource.create(
"okhttp",
okHttpClient
)
}
/**
* Provides [Retrofit] instance
*/
@Provides
@Singleton
fun provideRetrofit(okHttpClient: OkHttpClient) : Retrofit {
val contentType = "application/json".toMediaType()
return Retrofit.Builder()
.baseUrl("http://127.0.0.1:8080")
.client(okHttpClient)
.addConverterFactory(Json.asConverterFactory(contentType))
.build()
}
/**
* Provides [ApiService] instance
*/
@Provides
@Singleton
fun provideApiService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}
}
I do not know what I am missing so any help will be appreciated
Current Versions;
androidTestImplementation "com.squareup.okhttp3:mockwebserver:4.6.0"
androidTestImplementation 'com.jakewharton.espresso:okhttp3-idling-resource:1.0.0'
from Espresso Mock Web Server not waiting OkHttp Idling Resource with Dagger Hilt
No comments:
Post a Comment