如何为自动 Android Studio UI Espresso 测试套件模拟网络层响应?

How to mock network layer responses for automated Android Studio UI Espresso test suite?

我的目标是 运行 一套 Espresso UI 测试,并将在我的 MainActivity 的 onCreate 方法中创建的 Retrofit 实例重新配置为 return 模拟来自 localhost 的 JSON 响应,因此我可以测试应用程序的 UI 如何响应响应代码和不同的 JSON 数据等

到目前为止,我已经尝试放入 MockWebServer 包,并且我能够在本地主机服务器上启动并 运行ning。但是,Retrofit 实例仍然配置为生产 url。

我试过在测试启动时传递参数,包括使用一些 extras 手动设置 MainActivity 的意图,试图设置一个标志来切换用于 Retrofit 的字符串实例。但是,似乎在测试的 @Before 中设置的任何参数都不会在 MainActivity 启动时被提取。

我查看了这些答案,但似乎没有解决方案:

Android Espresso UI Test with mocked Retrofit API

Mock server requests Android Espresso UI Testing

这是我最近的实验:

@get:Rule
    var activityRule = ActivityTestRule(MainActivity::class.java, true, false)

    @Before
    fun setup() {

    }

    @Test
    fun intent() {
        val intent = Intent()

        activityRule.launchActivity(intent.putExtra("UITesting", true))

        println(activityRule.activity.intent.extras)
    }

这是 Retrofit 实例:

var BASE_URL = "https://api.invoicehome.com"

class NetworkManager {

    private val service : networkService
    // initialization with BASE_URL, using Gson converter factory to decode ( i believe there are other options available as well)
    init {
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        service = retrofit.create(networkService::class.java)
//    }
    }
 }

MainActivity 的开始,其中有一个 NetworkManager:

的实例
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    private var networkManager = NetworkManager()
}

我想要一些可以简单地环绕 Retrofit 实例并弹出 URL 的东西,但我 99% 确定这不现实。如果有任何 swift 开发人员在看这个,我正在寻找与 Swifter.

类似的功能

那么,我能否以某种方式使 URL 成为 Retrofit 实例的条件?我将在哪里传递这些标志?有没有我想念的图书馆可以为我完成所有这些工作?

您可以借助MockWebServer library

的帮助

您将需要抽象您的 NetworkManager class 并进行两种不同的实现,一种用于模拟请求,另一种用于发出真实请求并将其作为对您的 activity.

例如:

网络管理器界面

interface NetworkManager {

    fun doRequest()
}

模拟实施

class MockedNetworkManager : NetworkManager {

    override fun doRequest() {
        // Mock request
    }
}

实际实施

class RealNetworkManager : NetworkManager {

    override fun doRequest() {
        // Real request
    }
}

你的 MainActivity 应该看起来像这样

class MainActivity : AppCompatActivity() {

    private lateinit var networkManager: NetworkManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val shouldMock = intent.getBooleanExtra("UITesting", false)
        if (shouldMock) {
            networkManager = MockedNetworkManager()
        } else {
            networkManager = RealNetworkManager()
        }
    }

}