Java 机器人分子测试中Android活动中的模拟字段
因此,我正在使用遗留代码,我想对其中一个更简单的屏幕进行单元测试,即登录。 我没有任何DI框架 我使用robolectric 4.0.1和mockito 1.10.19 目前,由于我试图模拟的对象上存在空指针,我的测试失败: 测试类Java 机器人分子测试中Android活动中的模拟字段,java,android,unit-testing,mockito,robolectric,Java,Android,Unit Testing,Mockito,Robolectric,因此,我正在使用遗留代码,我想对其中一个更简单的屏幕进行单元测试,即登录。 我没有任何DI框架 我使用robolectric 4.0.1和mockito 1.10.19 目前,由于我试图模拟的对象上存在空指针,我的测试失败: 测试类 @RunWith(RobolectricTestRunner.class) public class LoginActivityTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.ru
@RunWith(RobolectricTestRunner.class)
public class LoginActivityTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
FirebaseInstanceId firebaseInstanceId;
@InjectMocks
private LoginActivity activity;
@Before
public void setup() {
when(firebaseInstanceId.getToken()).thenReturn("mockToken");
ActivityController<LoginActivity> activityController = Robolectric.buildActivity(LoginActivity.class);
activity = activityController.get();
initMocks(this);
activityController.create();
}
@Test
public void checkThatLoginButtonExists() {
// does not reach this point
Button btn = (Button) activity.findViewById(R.id.button_login);
assertNotNull("Button exisits", btn);
}
}
我主要是根据google的发现,在我的TestClass中重新排序指令,但似乎没有任何效果。
据我所知,调用getFireBaseInstanceId方法时,firebaseInstanceId不应为null,因为它在setup方法期间被注入initMocksthis
这适用于其他测试,但没有一个真正结合了robolectric和mockito
编辑1:
我已经将initMocksthis作为设置的第一行
我添加了一些System.out.println来看看会发生什么,我注意到LoginActivity构造函数会多次被调用,一次用于initmock,一次用于roblectric.buildActivity
编辑2:
我已将测试类中的设置更改如下
private void setMyOwnMock(String fieldName, Object inClass, Object mock ){
Field declaredField;
try {
declaredField = inClass.getClass().getDeclaredField(fieldName);
declaredField.setAccessible(true);
declaredField.set(inClass, firebaseInstanceId);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
@Before
public void setup() {
ActivityController<LoginActivity> activityController = Robolectric.buildActivity(LoginActivity.class);
activity = activityController.get();
setMyOwnMock("firebaseInstanceId", activity, firebaseInstanceId);
when(firebaseInstanceId.getToken()).thenReturn("mockToken");
// System.out.println(activity.firebaseInstanceId == null);
activityController.create();
}
虽然可能没有我想要的那么干净,但它可以在不更改生产代码的情况下完成工作。在这种情况下,注入和自动创建将不起作用。这:
@InjectMocks
private LoginActivity activity;
在设置中被以下内容覆盖:
ActivityController<LoginActivity> activityController =
Robolectric.buildActivity(LoginActivity.class);
activity = activityController.get();
然后我仍然得到默认的FirebaseApp在此过程中未初始化null。确保首先调用FirebaseApp.initializeAppContext。这是一个非法的状态异常,因为在Robolectric.buildActivity期间引发的getFirebaseInstanceId调用中firebaseInstanceId为null?这可能会起作用,我会尝试一下,但这意味着我更改生产代码仅仅是为了单元测试,这让我感到不舒服,特别是现在它停在firebase上,但以后可能会挂在其他地方。
ActivityController<LoginActivity> activityController =
Robolectric.buildActivity(LoginActivity.class);
activity = activityController.get();
@Before
public void setup() {
initMocks(this);
when(firebaseInstanceId.getToken()).thenReturn("mockToken");
ActivityController<LoginActivity> activityController =
Robolectric.buildActivity(LoginActivity.class);
activity = activityController.get();
activity.setFirebaseInstanceId(firebaseInstanceId);
activityController.create();