Android 单元测试失败 java.lang.IllegalArgumentException:需要 INTERNET 权限
Android Unit test fails with java.lang.IllegalArgumentException: INTERNET permission is required
我正在尝试为我的应用程序设置单元测试。但是我遇到了 Segment
的问题
这是我的测试class:
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.O_MR1])
class LoginViewModelTest {
private lateinit var viewModel: LoginViewModel
@Mock
private lateinit var authService: AuthService
@Mock
private lateinit var sharedPreferences: SharedPreferences
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
val mMyApplication = mock<Application>()
viewModel = LoginViewModel(mMyApplication, sharedPreferences, authService)
}
@Test
fun test_phone(){
viewModel.isPhone.observeForTesting {
val isPhone = LiveDataTestUtil.getValue(viewModel.isPhone) ?:
return@observeForTesting
Assert.assertFalse(isPhone)
}
}
}
失败并出现以下错误:
INTERNET permission is required.
java.lang.IllegalArgumentException: INTERNET permission is required.
at com.segment.analytics.Analytics$Builder.<init>(Analytics.java:1068)
at com.app.android.MyApplication.onCreate(MyApplication.kt:42)
MyApplication class 正在像这样初始化 Segment:
override fun onCreate() {
val analytics: Analytics = Analytics.Builder( //This is where its failing
applicationContext,
this.getString(R.string.segmentApiKey)
)
.trackApplicationLifecycleEvents()
.build()
// Set the initialized instance as a globally accessible instance.
Analytics.setSingletonInstance(analytics)
}
我在 Whosebug
中找到了
他们建议我们必须像这样初始化应用程序:
protected Context instance() {
ShadowApplication shadowApp = Shadows.shadowOf(this);
shadowApp.grantPermissions("android.permission.INTERNET");
return shadowApp.getApplicationContext();
}
像这样将 instance()
传递给段:
Analytics.with(instance()).identify("userId", null, null);
我认为这不是正确的方法,因为我们正在更改单元测试的代码,恕我直言,这不是正确的方法。
无论如何我都试过了,但是失败了,因为它无法解析shadowApp.getApplicationContext()
我通过添加这个来使用 shadowApplication
implementation 'org.robolectric:shadow-framework:4.6'
请帮我解决这个问题。提前致谢。
如果使用 ShadowApplication 是正确的方法,请帮助我了解发生了什么。我对这段代码片段的理解是它是一个示例应用程序 class 或可用于测试的东西。请cmiiw.
编辑:
我的 AndroidManifest.xml 已经拥有互联网权限
显然我的设置有问题
我添加了这些
// Required -- JUnit 4 framework
testImplementation 'junit:junit:4.13.2'
// Optional -- Robolectric environment
testImplementation 'androidx.test:core:1.4.0'
// Optional -- Mockito framework
testImplementation 'org.mockito:mockito-core:4.5.0'
// Optional -- mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"
// Optional -- Mockk framework
testImplementation 'io.mockk:mockk:1.12.3'
testImplementation 'androidx.test.ext:junit-ktx:1.1.3'
testImplementation 'org.robolectric:robolectric:4.6.1'
testImplementation 'org.mockito:mockito-inline:2.13.0'
testImplementation 'android.arch.core:core-testing:1.1.1'
并将我的测试 class 更改为如下所示:
@RunWith(MockitoJUnitRunner::class)
class LoginViewModelTest : TestCase() {
@get:Rule
var instantExecutorRule = InstantTaskExecutorRule()
private lateinit var viewModel: LoginViewModel
@Before
public override fun setUp() {
super.setUp()
val mMyApplication = mock(Application::class.java)
val sharedPreferences = mock(SharedPreferences::class.java)
val authService = mock(AuthService::class.java)
val analyticsFacade = mock(AnalyticsFacadeImpl::class.java)
doNothing().`when`(analyticsFacade).trackEvent(anyString(), any())
viewModel = LoginViewModel(
mMyApplication, sharedPreferences, authService,
analyticsFacade as AnalyticsFacadeImpl)
}
@Test
fun test_phone(){
viewModel.isPhone.observeForTesting {
val isPhone = LiveDataTestUtil.getValue(viewModel.isPhone) ?:
return@observeForTesting
Assert.assertFalse(isPhone)
}
}
}
我正在尝试为我的应用程序设置单元测试。但是我遇到了 Segment
的问题这是我的测试class:
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.O_MR1])
class LoginViewModelTest {
private lateinit var viewModel: LoginViewModel
@Mock
private lateinit var authService: AuthService
@Mock
private lateinit var sharedPreferences: SharedPreferences
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
val mMyApplication = mock<Application>()
viewModel = LoginViewModel(mMyApplication, sharedPreferences, authService)
}
@Test
fun test_phone(){
viewModel.isPhone.observeForTesting {
val isPhone = LiveDataTestUtil.getValue(viewModel.isPhone) ?:
return@observeForTesting
Assert.assertFalse(isPhone)
}
}
}
失败并出现以下错误:
INTERNET permission is required.
java.lang.IllegalArgumentException: INTERNET permission is required.
at com.segment.analytics.Analytics$Builder.<init>(Analytics.java:1068)
at com.app.android.MyApplication.onCreate(MyApplication.kt:42)
MyApplication class 正在像这样初始化 Segment:
override fun onCreate() {
val analytics: Analytics = Analytics.Builder( //This is where its failing
applicationContext,
this.getString(R.string.segmentApiKey)
)
.trackApplicationLifecycleEvents()
.build()
// Set the initialized instance as a globally accessible instance.
Analytics.setSingletonInstance(analytics)
}
我在 Whosebug
中找到了他们建议我们必须像这样初始化应用程序:
protected Context instance() {
ShadowApplication shadowApp = Shadows.shadowOf(this);
shadowApp.grantPermissions("android.permission.INTERNET");
return shadowApp.getApplicationContext();
}
像这样将 instance()
传递给段:
Analytics.with(instance()).identify("userId", null, null);
我认为这不是正确的方法,因为我们正在更改单元测试的代码,恕我直言,这不是正确的方法。
无论如何我都试过了,但是失败了,因为它无法解析shadowApp.getApplicationContext()
我通过添加这个来使用 shadowApplication
implementation 'org.robolectric:shadow-framework:4.6'
请帮我解决这个问题。提前致谢。
如果使用 ShadowApplication 是正确的方法,请帮助我了解发生了什么。我对这段代码片段的理解是它是一个示例应用程序 class 或可用于测试的东西。请cmiiw.
编辑:
我的 AndroidManifest.xml 已经拥有互联网权限
显然我的设置有问题
我添加了这些
// Required -- JUnit 4 framework
testImplementation 'junit:junit:4.13.2'
// Optional -- Robolectric environment
testImplementation 'androidx.test:core:1.4.0'
// Optional -- Mockito framework
testImplementation 'org.mockito:mockito-core:4.5.0'
// Optional -- mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"
// Optional -- Mockk framework
testImplementation 'io.mockk:mockk:1.12.3'
testImplementation 'androidx.test.ext:junit-ktx:1.1.3'
testImplementation 'org.robolectric:robolectric:4.6.1'
testImplementation 'org.mockito:mockito-inline:2.13.0'
testImplementation 'android.arch.core:core-testing:1.1.1'
并将我的测试 class 更改为如下所示:
@RunWith(MockitoJUnitRunner::class)
class LoginViewModelTest : TestCase() {
@get:Rule
var instantExecutorRule = InstantTaskExecutorRule()
private lateinit var viewModel: LoginViewModel
@Before
public override fun setUp() {
super.setUp()
val mMyApplication = mock(Application::class.java)
val sharedPreferences = mock(SharedPreferences::class.java)
val authService = mock(AuthService::class.java)
val analyticsFacade = mock(AnalyticsFacadeImpl::class.java)
doNothing().`when`(analyticsFacade).trackEvent(anyString(), any())
viewModel = LoginViewModel(
mMyApplication, sharedPreferences, authService,
analyticsFacade as AnalyticsFacadeImpl)
}
@Test
fun test_phone(){
viewModel.isPhone.observeForTesting {
val isPhone = LiveDataTestUtil.getValue(viewModel.isPhone) ?:
return@observeForTesting
Assert.assertFalse(isPhone)
}
}
}