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

时间:2019-05-11 21:19:16

标签: android testing mocking retrofit uitest

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

到目前为止,我已经尝试放入MockWebServer软件包,并且能够将其启动并在localhost服务器上运行。但是,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%的确定这是不现实的。如果有任何敏捷的开发人员正在研究这个问题,我正在寻找与Swifter类似的功能。

因此,我可以以某种方式使URL适用于Retrofit实例吗?我将这些标志传递到哪里?我缺少一个可以为我完成所有这些工作的图书馆吗?

1 个答案:

答案 0 :(得分:0)

您可以使用MockWebServer library

的帮助

您将需要抽象您的NetworkManager类并进行两种不同的实现,一种用于模拟请求,另一种用于进行实际请求,并将其作为对您活动的依赖。

例如:

NetworkManager界面

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

}