Mr.*_*bot 6 android unit-testing mockito extras android-intent
我正在尝试验证是否将特定的附加功能添加到了 Intent,但是我一直在单元测试 Android 中为 Intent 获取空值。我有以下课程需要测试:
public class TestClass extends SomeNotifier {
private Intent mIntent = new Intent("testintent");
public TestClassConstructor(Context context) {
super(context);
}
@Override
public void notifyChange() {
mIntent.putExtra("Key one", 22);
mIntent.putExtra("Key two", 23);
mIntent.putExtra("Key three", 24);
getContext().sendBroadcast(mIntent);
}
}
Run Code Online (Sandbox Code Playgroud)
测试如下(我也尝试过使用 mockIntent,但结果是一样的,额外的还是空的):
@RunWith(MockitoJUnitRunner.class)
public class TestClassTest {
@Mock
Context mMockContext;
@Test
public void sendBroadcastTest() {
ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class);
TestClass testClassNotifier = new TestClass (mMockContext);
testClassNotifier.notifyChange();
verify(mMockContext).sendBroadcast(argument.capture());
Intent intent = argument.getValue();
//THE INTENT IS NULL
Assert.assertTrue(intent.hasExtra("Key one"));
}
}
Run Code Online (Sandbox Code Playgroud)
你有什么建议我应该如何使这个测试工作?提前致谢
Intent和其他类似的 Android 运行时类Context默认情况下仅在物理 Android 手机和模拟器上可用。对于本地单元测试,您将获得一个运行时的存根版本,默认情况下Intent等方法将返回null。请参阅此问题以获取解释。
这意味着您当前的测试正在验证一个已删除的版本,默认情况下,所有方法调用Intent都会返回该版本null。
有一些方法可以解决这个问题 - 您可以将测试转换为仪器化单元测试,这意味着您必须在真正的手机或模拟器上运行它。或者,您可以Intent使用您控制的类包装该类。
也许最好的解决方案是使用像Robolectric这样的框架。这将为您提供重要 Android 类的工作测试替身(称为阴影),例如Intent在您的 IDE 中运行的本地单元测试。
仔细安装 Robolectric 后,您只需添加以下内容即可进行测试:
@RunWith(RobolectricTestrunner.class)
public class TestClassTest {
Run Code Online (Sandbox Code Playgroud)
顺便说一句,请确保您在 Android 上使用了正确的 Mockito 依赖项:
testCompile 'org.mockito:mockito-core:2.8.9'
androidTestCompile 'org.mockito:mockito-android:2.8.9'
Run Code Online (Sandbox Code Playgroud)
您可以使用 Mockk 进行模拟intent
@Test
fun `Test`() {
// Arrange
val longValue = 1000L
val enumValue = ModelEnum.MODEL1
val intentMock = spyk<Intent>()
every { intentMock.extras?.getLong("KEY_LONG_VALUE") } returns longValue
every { intentMock.hasExtra(CheckoutRouter.RESULT_PAYMENT_TYPE) } returns true
every { intentMock.getSerializableExtra("KEY_ENUM_VALUE") } returns enumValue
// Action
val a = A(intent = intentMock)
val longValueResult = a.getLongValue()
val enumValueResult = a.getEnumValue()
// Assert
Assert.assertEquals(longValue, longValueResult)
Assert.assertEquals(enumValue, enumValueResult)
}
class A (val intent: Intent){
fun getLongValue():Long? {
return intent.extras?.getLong("KEY_LONG_VALUE")
}
fun getEnumValue():ModelEnum? {
return intent.getSerializableExtra("KEY_ENUM_VALUE") as? ModelEnum
}
}
enum class ModelEnum{
MODEL1,MODEL2
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5828 次 |
| 最近记录: |