robolectric 3.0 Mockito -- 如何在 activity 中模拟 class
robolectric 3.0 Mockito -- how to mock a class inside activity
我正在迁移到 robolectric 3.0
问题陈述--
我有一个 class AppUtility,它在 MyActivity 中实例化,所以要检查它的方法是否被调用,我需要在设置 MyActivity 之前在我的测试中模拟它。
这是我的代码:
@Mock
private AppUtility mockAppUtility;
@Before
public void setUp() {
initMocks(this);
myActivity= Robolectric.setupActivity(MyActivity.class);
equalsButton = (Button) myActivity.findViewById(R.id.equals_sign);
shadowActivity = Shadows.shadowOf(myActivity);
}
测试方法如下:--
@Test
public void shouldCallStartAlarm() {
for (int i = 0; i < 4; i++) {
equalsButton.performClick();
}
verify(mockAppUtility).startAlarm();
}
Bu 我收到以下错误消息:-- 哪个 show mock 没有链接到 activity,我如何才能将它绑定到 activity?
Actually, there were zero interactions with this mock.
但是模拟对象与测试没有关联。对于 Robolectric 的早期版本,我使用将模拟对象关联到 activity 创建时,通过如下覆盖它
myActivity = new MyActivity() {
@Override
AppUtility getUtil() {
return mockAppUtility;
}
};
myActivity.onCreate(new Bundle());
它过去工作正常,使用 Robolectric 3.0,我如何在启动 activity 之前绑定模拟对象。
关注@nenick 你的第二个 option:This 是它的样子
@Mock
private AppUtility appUtility;
@InjectMocks
private MyActivity myActivity;
@Before
public void setUp() {
ActivityController<MyActivity> activityController = Robolectric.buildActivity(MyActivity.class);
// myActivity= Robolectric.setupActivity(MyActivity.class);
myActivity=activityController.get();
initMocks(this);
activityController.setup();
equalsButton = (Button) myActivity.findViewById(R.id.equals_sign);
// shadowActivity = Shadows.shadowOf(calculatorActivity);
}
但我遇到异常:-
java.lang.IllegalArgumentException: attempted to invoke public final android.app.Application org.robolectric.shadows.ShadowActivity.getApplication() on instance of class org.com.android.AppUtility$$EnhancerByMockitoWithCGLIB$c74666, but AppUtility$$EnhancerByMockitoWithCGLIB$c74666 doesn't extend ShadowActivity
it breaks at step--activityController.setup();
单元测试的主要规则之一——永远不要在测试下模拟 class。你可能会 spy
但它又是救援挑战,你不应该在这种情况下使用它。
另一个 smell
显示您已进行唤醒测试 - 当您能够 运行 此测试成功时,它不能保证真正的警报设置。它将仅保证调用此方法。因此,最好验证设置警报而不是验证方法调用。检查 this link 影子警报管理器的使用示例
使用 mockito 模拟注入功能,只需设置模拟即可。
@Mock
private AppUtility mockAppUtility;
@InjectMocks
Activity mActivity;
@Before
public void setUp() {
myActivity= Robolectric.setupActivity(MyActivity.class);
equalsButton = (Button) myActivity.findViewById(R.id.equals_sign);
shadowActivity = Shadows.shadowOf(myActivity);
// create and injects mocks into object annotated with @InjectMocks
initMocks(this);
}
要在调用 activity 设置 (onCreate, ...) 之前设置模拟,您必须在设置之前访问您的 activity。
@Before
public void setUp() {
ActivityController<Activity> activityController = Robolectric.buildActivity(Activity.class);
// get the activity instance
mActivity = activityController.get()
initMocks(this);
// now setup your activity after mock injection
activityController.setup()
}
我正在迁移到 robolectric 3.0
问题陈述--
我有一个 class AppUtility,它在 MyActivity 中实例化,所以要检查它的方法是否被调用,我需要在设置 MyActivity 之前在我的测试中模拟它。
这是我的代码:
@Mock
private AppUtility mockAppUtility;
@Before
public void setUp() {
initMocks(this);
myActivity= Robolectric.setupActivity(MyActivity.class);
equalsButton = (Button) myActivity.findViewById(R.id.equals_sign);
shadowActivity = Shadows.shadowOf(myActivity);
}
测试方法如下:--
@Test
public void shouldCallStartAlarm() {
for (int i = 0; i < 4; i++) {
equalsButton.performClick();
}
verify(mockAppUtility).startAlarm();
}
Bu 我收到以下错误消息:-- 哪个 show mock 没有链接到 activity,我如何才能将它绑定到 activity?
Actually, there were zero interactions with this mock.
但是模拟对象与测试没有关联。对于 Robolectric 的早期版本,我使用将模拟对象关联到 activity 创建时,通过如下覆盖它
myActivity = new MyActivity() {
@Override
AppUtility getUtil() {
return mockAppUtility;
}
};
myActivity.onCreate(new Bundle());
它过去工作正常,使用 Robolectric 3.0,我如何在启动 activity 之前绑定模拟对象。
关注@nenick 你的第二个 option:This 是它的样子
@Mock
private AppUtility appUtility;
@InjectMocks
private MyActivity myActivity;
@Before
public void setUp() {
ActivityController<MyActivity> activityController = Robolectric.buildActivity(MyActivity.class);
// myActivity= Robolectric.setupActivity(MyActivity.class);
myActivity=activityController.get();
initMocks(this);
activityController.setup();
equalsButton = (Button) myActivity.findViewById(R.id.equals_sign);
// shadowActivity = Shadows.shadowOf(calculatorActivity);
}
但我遇到异常:-
java.lang.IllegalArgumentException: attempted to invoke public final android.app.Application org.robolectric.shadows.ShadowActivity.getApplication() on instance of class org.com.android.AppUtility$$EnhancerByMockitoWithCGLIB$c74666, but AppUtility$$EnhancerByMockitoWithCGLIB$c74666 doesn't extend ShadowActivity
it breaks at step--activityController.setup();
单元测试的主要规则之一——永远不要在测试下模拟 class。你可能会 spy
但它又是救援挑战,你不应该在这种情况下使用它。
另一个 smell
显示您已进行唤醒测试 - 当您能够 运行 此测试成功时,它不能保证真正的警报设置。它将仅保证调用此方法。因此,最好验证设置警报而不是验证方法调用。检查 this link 影子警报管理器的使用示例
使用 mockito 模拟注入功能,只需设置模拟即可。
@Mock
private AppUtility mockAppUtility;
@InjectMocks
Activity mActivity;
@Before
public void setUp() {
myActivity= Robolectric.setupActivity(MyActivity.class);
equalsButton = (Button) myActivity.findViewById(R.id.equals_sign);
shadowActivity = Shadows.shadowOf(myActivity);
// create and injects mocks into object annotated with @InjectMocks
initMocks(this);
}
要在调用 activity 设置 (onCreate, ...) 之前设置模拟,您必须在设置之前访问您的 activity。
@Before
public void setUp() {
ActivityController<Activity> activityController = Robolectric.buildActivity(Activity.class);
// get the activity instance
mActivity = activityController.get()
initMocks(this);
// now setup your activity after mock injection
activityController.setup()
}