【问题标题】:Cleanest way to wrap Java static methods in a non-static object (refactoring to allow mocking)将 Java 静态方法包装在非静态对象中的最简洁方法(重构以允许模拟)
【发布时间】:2021-11-02 15:16:42
【问题描述】:

我正在使用 Java 和 Kotlin,代码库有一些遗留的静态逻辑,这些逻辑确实应该在对象中,但现在太复杂了,无法制作非静态的。我希望能够干净地测试(使用这些静态依赖项的模拟)一些(非静态)依赖于这个静态逻辑的类,所以我想将静态逻辑类包装在非静态虚拟包装器中,即实例化对象,其实例方法只是调用它们的静态对应物。然后我将在单元测试中模拟这些包装器(我不想只使用静态模拟)。

手动执行此操作的方法是为每个静态逻辑类Foo 使用方法public static void bar(),使用方法public void bar() 定义一个新类public void bar(),它只调用Foo.bar(),实例化一个FooWrapper 在我班上的佼佼者,并将所有当前呼叫切换到Foo.bar(),而不是呼叫fooWrapperInstance.bar()

上述工作正常,但涉及很多无聊 Wrapper 类,除了传递调用什么都不做。是否有一些语法糖(Java 或 Kotlin 都可以,但它必须与 Java 一起使用)可以为我创建或至少缩短这些包装类?我对 Guava 的 ForwardingObject 很熟悉,但它似乎只有在底层逻辑已经在一个实例中时才有效,而我的不是。

【问题讨论】:

    标签: java kotlin mockito


    【解决方案1】:

    编写包装器的最短方法是使用方法引用,如下所示。

    假设你有这个 Java 类

    public class A {
        static String hello() {
            return "";
        }
    }
    

    然后你想像这样在 Kotlin 中为它创建一个包装器

    class AKotlin {
        val hello = A::hello
    }
    

    现在AKotlin::hello 将具有与静态A::hello 方法相同的签名,但将改为对象方法

    【讨论】:

    • 这是有道理的(我认为这是最干净的自己写选项),但我真正想要的是自动生成 AKotlin 类的东西,或者至少类中的val hello = A::hello 映射。我试图避免手动映射f1f2f3f4...fn
    猜你喜欢
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多