使用JUnit+(Robolectric或Mockito或两者都在Android中)编写单元测试用例

43
这是我第一次在Android中编写单元测试用例,我已经搜索了很多东西。我有一些关于Robolectric和Mockito的疑问:
1. 我是否应该仅将Robolectric与JUnit一起在Android应用程序中使用? 2. 我是否应该仅将Mockito与JUnit一起在Android应用程序中使用? 3. 我是否应该同时使用这两个框架? 4. Mockito和Robolectric之间有什么区别?
我已经搜索了Mokito和Robolectric之间的区别,但没有找到合适的答案。请给予建议。
3个回答

50

它们的使用方法略有不同,我倾向于在我的项目中同时使用两者。

Mockito

用于创建你的类的mocks。

当你测试某个类时,你会使用Mockito来mock该类的所有依赖项。

尽可能地,大部分测试应该使用mockito。为了实现这一点,大多数人将其代码拆分成MVP等,其中业务逻辑与View逻辑分离。这样,你的业务逻辑(Presenter)对Android库没有任何了解(或依赖),也不需要对它们进行模拟。

Robolectric

是一个包含许多Android类的模拟库。

Robolectric测试运行器在运行测试时将这些“影子对象”注入到实际的Android类中。这就是允许测试在JVM上运行而不启动Android实例的方式。

在使用MVP时,你的View层通常由Activity/Fragment实现,这就是你可以使用Robolectric来模拟这些内容的地方。

注意事项

只有在必要的情况下才使用Robolectric。它基本上重新实现了Android框架的某些部分,但并不总是完全相同。

你可能还需要另一个库,如PowerMock。它允许模拟静态类,例如Math,或者用于模拟静态Android类,如TextUtils。

两者都与JUnit一起使用。


我有Activity和Fragment,所以我会使用robolectric,并且对于与web服务相关的模型类,我会使用mockito。对吗? - Deepanker Chaudhary
正如Jahnold所说,Robolectric是一个替代Android特定库的库。您这样做是为了在PC或Linux平台上使用Java VM进行单元测试。如果您在模拟器或USB连接的Android设备上执行单元测试,则不使用Robolectric。Mockito是一个框架,用于替换系统中不想在另一个模块的单元测试中使用的模块 - 我们称之为“mock”依赖模块。 - Robert R Evans
嘿,感谢提供的信息。我对使用Junit + Roboectric运行测试感到困惑,主要是因为测试类顶部的@ RunWith(AndroidJUnit4.class)这一行。所以它应该使用Junit还是使用robo来运行? - Doug Ray
@Jahnold 谢谢,我会尝试在Roboeletric测试运行器上运行一些测试。 - Doug Ray
@Jahnold,我需要运行测试用例来执行我的Android应用程序中的服务层。那么,哪个框架是理想的?Robolectric还是Mockito?而且以后这将成为一个完整的应用程序。我听说对于UI测试,Espresso是理想的选择。 - Mr.G
显示剩余3条评论

15

Mockito单独可以涵盖大多数情况。

然而,Robolectric也可以在单元测试中对Android组件(如Activity或Fragment)提供有限的操作(不依赖于Android SDK的仪器测试),这不需要任何模拟器或设备,并且比仪器测试快得多。

我的建议是:在Android中使用Mockito进行单元测试和Espresso进行UI测试,因为它们是半官方的Android测试框架。

如果在Android SDK上有一些依赖关系,请将Robolectric添加到您的单元测试中。


我有活动和片段以及网络服务。我只需要进行单元测试而不是仪器测试。因此,我了解Robolectric,但我不太清楚在哪里使用Robolectric或Mockito。 或者Mockito只用于模型类? - Deepanker Chaudhary
除此之外,根据您的评论,如果您的业务逻辑层完全独立于Android框架,则应使用带有Mockito的JUnit,只有当您的业务逻辑层具有Android框架依赖性时,您才需要使用Roboelectric。 - Talha

-1
首先,我们需要了解Roboelectric和Mockito是在Android测试驱动开发中常用的两个不同工具。因此,在同一个项目中通常会同时使用这两个工具。
下面我将解释它们的常见用例:
Mockito用于模拟依赖项,这意味着如果您想在测试环境中访问真实对象,则需要伪造它或者说模拟它。现在使用Mockito很容易对对象进行模拟。
Roboelectric是Android行业标准的单元测试框架。使用Robolectric,您的测试在JVM内的模拟Android环境中运行,而不需要模拟器的开销。使用Roboelectric编写的简单测试如下:
`@RunWith(AndroidJUnit4.class)
public class MyActivityTest {
@Test
public void clickingButton_shouldChangeResultsViewText() throws Exception {
Activity activity = Robolectric.setupActivity(MyActivity.class);

Button button = (Button) activity.findViewById(R.id.press_me_button);
TextView results = (TextView) activity.findViewById(R.id.results_text_view);

button.performClick();
assertThat(results.getText().toString(), equalTo("Testing Android Rocks!"));
}
}`

我只是想问为什么在单元测试中需要使用Dagger?将其他功能依赖项注入到单元中不再是“单元”测试。如果测试需要其他依赖项,那么它不应该被称为集成测试吗?我对单元测试还很陌生,不太清楚哪个是哪个。如果Dagger的目的是将“虚拟”依赖项注入到单元测试中,那么直接模拟它不是更容易吗? - gmatcat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接