如何在Kotlin中模拟静态方法?

5

我正在尝试在Kotlin中使用jMockit模拟静态方法:

object: MockUp<System>() {
  @Mock
  fun getProperty(name: String) = "tagB"
}

但是我收到了以下错误信息:
无法加载Logmanager "tagB" java.lang.ClassNotFoundException: tagB 在java.net.URLClassLoader.findClass(URLClassLoader.java:381)中 在java.lang.ClassLoader.loadClass(ClassLoader.java:424)中 在sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.java:331)中 在java.lang.ClassLoader.loadClass(ClassLoader.java:357)中 在java.util.logging.LogManager $ 1.run(LogManager.java:195)中 在java.util.logging.LogManager $ 1.run(LogManager.java:181)中 在java.security.AccessController.doPrivileged(Native Method)中 在java.util.logging.LogManager。 (LogManager.java:181) 在java.util.logging.Logger.getPlatformLogger(Logger.java:572)中 在java.util.logging.LoggingProxyImpl.getLogger(LoggingProxyImpl.java:41)中 在sun.util.logging.LoggingSupport.getLogger(LoggingSupport.java:100)中 在sun.util.logging.PlatformLogger $ JavaLoggerProxy。 (PlatformLogger.java:602) 在sun.util.logging.PlatformLogger $ JavaLoggerProxy。 (PlatformLogger.java:597) 在sun.util.logging.PlatformLogger。 (PlatformLogger.java:239) 在sun.util.logging.PlatformLogger.getLogger(PlatformLogger.java:198)中 在sun.util.locale.provider.LocaleServiceProviderPool.config(LocaleServiceProviderPool.java:142)中 在sun.util.locale.provider.LocaleProviderAdapter。 (LocaleProviderAdapter.java:165) 在java.text.DecimalFormatSymbols.getInstance(DecimalFormatSymbols.java:178)中 在java.util.Formatter.getZero(Formatter.java:2283)中 在java.util.Formatter。 (Formatter.java:1892) 在java.util.Formatter。 (Formatter.java:1914) 在java.lang.String.format(String.java:2940)中 在org.junit.runner.Description.formatDisplayName(Description.java:114)中 在org.junit.runner.Description.createTestDescription(Description.java:73)中 在io.kotlintest.TestCase.getDescription(testcase.kt:45)中 在io.kotlintest.TestBase.descriptionForSuite $ kotlintest_main(TestBase.kt:153)中 在io.kotlintest.TestBase.getDescription $ kotlintest_main(TestBase.kt:39)中 在io.kotlintest.KTestJUnitRunner.getDescription(KTestJUnitRunner.kt:11)中 在com.intellij.junit4.JUnit4IdeaTestRunner.getDescription(JUnit4IdeaTestRunner.java:123)中 在com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:99)中 在com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)中 在com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)中 在com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)中 在sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)中 在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)中 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中 在java.lang.reflect.Method.invoke(Method.java:498)中 在com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)中 记录配置类 "tagB" 失败 java.lang.ClassNotFoundException: tagB

其他基于期望块的方法也没有成功。

我如何在Kotlin中模拟静态方法?


为什么不重构你的代码,使其通过显式API传递你正在访问的任何值,而不是通过System.getProperty - yole
在这种情况下,没有什么需要模拟的:只需调用 System.setProperty(...) - Rogério
@Rogério,“System.setProperty”不是一个选项(实际上它是当前的“解决方案”),因为它会干扰其他测试。 - deamon
1个回答

4
你应该像这样模拟System:
class MockSystem : MockUp<System>() {
    @Mock
    fun getProperty(name: String) = "tagB"
}


class MockTest {

    val m = MockSystem();

    @Test fun test() {
        Assert.assertEquals(System.getProperty("hello"), "tagB")
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接