Espresso Mock Web 服务器不等待 OkHttp 空闲资源和 Dagger Hilt

ysf*_*yln 9 android okhttp android-espresso mockwebserver dagger-hilt

我正在尝试使用Espresso和为我的 Fragments 编写 UI 测试MockWebServer。我OkHttp Idling Resource用来告诉 Espresso 等待 API 调用完成。

但不知何故,有时我的测试有效,但有时无效,因为Espresso在服务请求之前就完成了它的工作。所以我的 recyclerView 项目点击测试失败。

我不明白为什么 espresso 不等待 API 调用?任何人都可以帮忙吗?

这是我的测试课

@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()
    }

}
Run Code Online (Sandbox Code Playgroud)

这是我的TestNetworkModule网络依赖项

@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)
    }

}
Run Code Online (Sandbox Code Playgroud)

我不知道我错过了什么,所以任何帮助将不胜感激

当前版本;

androidTestImplementation "com.squareup.okhttp3:mockwebserver:4.6.0"
androidTestImplementation 'com.jakewharton.espresso:okhttp3-idling-resource:1.0.0'
Run Code Online (Sandbox Code Playgroud)