英文:
Log.w() throws `java.lang.RuntimeException: Stub!` despite `@PrepareForTest(Log.class)`
问题
我正在尝试为间接使用Log.w()
的类编写JUnit(5)测试。
当我首次遇到java.lang.RuntimeException: Stub!
作为结果时,我迅速发现这是Android开发中众所周知的问题,我可以使用模拟:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Log.class)
class mySusuManager {
...
}
在我的应用的build.gradle中使用以下dependencies {}
:
testImplementation "org.junit.jupiter:junit-jupiter-api:5.9.1"
testImplementation "org.junit.jupiter:junit-jupiter-params:5.9.1"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.9.1"
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.9.1"
testImplementation 'junit:junit:4.13.2'
testImplementation "org.mockito:mockito-core:4.5.1"
testImplementation "org.powermock:powermock-core:2.0.9"
testImplementation "org.powermock:powermock-module-junit4:2.0.9"
testImplementation "org.powermock:powermock-api-mockito2:2.0.9"
或者使用gradle标志:
android {
testOptions {
unitTests.returnDefaultValues = true
}
}
我尝试了两者(不同时),但仍然遇到了可怕的:
"C:\Program Files\Android\Android Studio\jre\bin\java.exe" ...
java.lang.RuntimeException: Stub!
at android.util.Log.w(Log.java:37)
...
我可能漏掉了什么?
英文:
I am trying to write a JUnit (5) for a class that indirectly uses Log.w()
.
When I first encountered java.lang.RuntimeException: Stub!
as a result, I quickly found out that this is a well known issue in Android development and that I can either use mocking:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Log.class)
class mySusuManager {
...
}
with the following dependencies {}
in my app's build.gradle:
testImplementation "org.junit.jupiter:junit-jupiter-api:5.9.1"
testImplementation "org.junit.jupiter:junit-jupiter-params:5.9.1"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.9.1"
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.9.1"
testImplementation 'junit:junit:4.13.2'
testImplementation "org.mockito:mockito-core:4.5.1"
testImplementation "org.powermock:powermock-core:2.0.9"
testImplementation "org.powermock:powermock-module-junit4:2.0.9"
testImplementation "org.powermock:powermock-api-mockito2:2.0.9"
or use a gradle flag:
android {
testOptions {
unitTests.returnDefaultValues = true
}
}
I tried both (not simultaneously), but I am still getting the dreaded:
"C:\Program Files\Android\Android Studio\jre\bin\java.exe" ...
java.lang.RuntimeException: Stub!
at android.util.Log.w(Log.java:37)
...
What could I be missing?
答案1
得分: 1
为了所有人的利益,我在这里发布了我如何间接解决我的问题。
大多数现有的SO参考资料都涉及到比今天可用的工具和库版本旧的java.lang.RuntimeException: Stub!
问题。
因此,感谢文章如何使用Mockito模拟静态方法,我发现在引入Mockito 3.x后,我不需要使用PowerMock来模拟android.util.Log
类。
这是我完成这个任务的步骤:
步骤1:我删除了我的mySusuManagerTest
类定义之前的以下内容:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Log.class)
步骤2:我将所有的PowerMock导入替换为一个单一的导入:
import org.mockito.Mockito;
步骤3:在build.gradle
中,我用一个单一的mockito-inline
类引用替换了所有testImplementation "org.powermock
出现的地方以及testImplementation "org.powermock:powermock-core
。
implementation "org.mockito:mockito-inline:4.11.0"
步骤4:在测试方法中,我只放了一行mockStatic
代码:
@Test
void thisIsTheMethodImTesting() {
Mockito.mockStatic(Log.class);
// 在此处放置测试 + 断言代码
}
英文:
For the benefit of all, I am posting here how I solved my issue, indirectly.
Most existing SO references to this java.lang.RuntimeException: Stub!
issue seem to referring to versions of the tools and libraries that are older than what is available today.
So, thanks to the article How to mock static methods with Mockito, I discovered that with the introduction of Mockito 3.x, I do not need PowerMock to mock the android.util.Log
class.
Here is how I accomplished this:
Step 1: I removed the
@RunWith(PowerMockRunner.class)
@PrepareForTest(Log.class)
above my mySusuManagerTest
class definition.
Step 2: I replaced all powermock imports with a single:
import org.mockito.Mockito;
Step 3: In build.gradle
I replaced all testImplementation "org.powermock
occurrences and the testImplementation "org.powermock:powermock-core
one, with a single mockito-inline
class reference.
implementation "org.mockito:mockito-inline:4.11.0"
Step 4: Inside the test method, I only placed a single mockStatic
line:
@Test
void thisIsTheMethodImTesting() {
Mockito.mockStatic(Log.class);
// test + assert code here
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论