我有这种制作方法:
public boolean onShouldOverrideUrlLoading(String url) {
boolean isConsumed = false;
if (url.contains("code=")) {
Uri uri = Uri.parse(url);
String authCode = uri.getQueryParameter("code");
mView.authCodeObtained(authCode);
isConsumed = true;
}
return isConsumed;
}
我有这个Mockito测试方法:
@Test
public void onShouldOverrideUrlLoadingOnAuthCodeObtained(){
String code = "someCode";
boolean isConsumed = mPresenter.onShouldOverrideUrlLoading("http://localhost/?code=" + code);
verify(mView, times(1)).authCodeObtained(code);
assertEquals(isConsumed, true);
}
但似乎一旦代码运行并且它到达Uri.parse(url),我得到一个空指针。我错过了什么?在生产中,这非常有效。只有在测试时,Uri.parse()才会返回null。
谢谢!
答案 0 :(得分:17)
最终我在Mockito上使用了PowerMock来模拟Uri类。 使用这些依赖项添加它:
'org.powermock:powermock-api-mockito:1.4.12'
'org.powermock:powermock-module-junit4:1.6.2'
了解它here。
它使您可以模拟静态方法,私有方法,最终类等。 在我的测试方法中,我使用了:
PowerMockito.mockStatic(Uri.class);
Uri uri = mock(Uri.class);
PowerMockito.when(Uri.class, "parse", anyString()).thenReturn(uri);
这传递了实际代码中的行并返回了一个Mocked Uri对象,因此测试可以向前移动。 请务必添加:
@RunWith(PowerMockRunner.class)
@PrepareForTest({Uri.class})
作为测试类名称之上的注释。
使用Robolectric解决这个问题也是一种有效的技术。
希望这会有所帮助。
答案 1 :(得分:3)
这里的问题是用于运行单元测试的android.jar
文件不包含任何实际代码。
这种方式android.net.Uri
默认返回null
并使用
android {
// ...
testOptions {
unitTests.returnDefaultValues = true
}
}
不会解决此情况的问题,因为方法的默认返回值仍为null
我的解决方案是使用Unmock插件,其唯一目的是取消android.jar
中的某些类/包,并为这些提供完整的实现。
在这种特定情况下,只需将代码段添加到build.gradle
文件
apply plugin: 'de.mobilej.unmock'
//...
unMock {
keepStartingWith "android.net.Uri"
}
答案 2 :(得分:2)
我使用Roboelectric测试跑步者来解决这个问题。
{{1}}
答案 3 :(得分:2)
我能够使用 android.net.Uri
使用 AndroidJUnit4
runner 如下
import androidx.core.net.toUri
import androidx.test.ext.junit.runners.AndroidJUnit4
...
@RunWith(AndroidJUnit4::class)
class FileTest {
@get:Rule(order = 0)
val tempFolder = TemporaryFolder()
private lateinit var tempFile: File
@Before
fun setup() {
tempFile = tempFolder.newFile()
}
@Test
fun test_fileUri_not_null() {
assertTrue(tempFile.exists())
assertNotNull(tempFile.toUri())
}
}
以上测试写在tests
目录下
答案 4 :(得分:1)
问题可能在于Uri
类,因为正在测试的代码是静态代码(Uri.parse(...)
),Uri
可能在测试环境中严重初始化。请注意Android SDK中有两个uri类:
我不是Android开发人员,但您可能想要检查测试环境。
答案 5 :(得分:1)
如果您使用android.net.Uri类,那么您需要在Mockito之上使用Robolectric(http://robolectric.org)运行测试
答案 6 :(得分:1)
我在使用android.net.Uri
类进行测试时遇到了类似的问题。
我已经解决了将测试从'test'文件夹移动到'androidTest'并在设备中运行它的问题。在设备中,Uri
类的行为正常。
答案 7 :(得分:0)
我通过使用“ @RunWith(RobolectricTestRunner :: class)”运行测试套件解决了该问题。