【问题标题】:Spock:Testing tightly Coupled ClassesSpock:测试紧耦合类
【发布时间】:2021-01-23 01:33:47
【问题描述】:

我们如何测试与另一个类 Y 紧密耦合的类 X Y.add 方法是否被调用

class X {
    fun sum(a: Int, b: Int, c: Int) {
        val y = Y()
        y.add(a, b)
    }
}

class Y {
    fun add(a: Int, b: Int) {}
}

我还想要一个返回 add >> 10 的 Y 存根

【问题讨论】:

    标签: java unit-testing kotlin mocking spock


    【解决方案1】:

    Spock 支持模拟和验证被模拟对象的方法被调用了多少次。这里的问题是,在上面的实现中,无法从 X.sum 方法内部访问 Y 类的模拟实例。 如果您在 Y 的实例在其构造函数中传递/作为sum 方法的参数时以某种方式重写 X 类:

    class X {
        fun sum(a: Int, b: Int, y: Y) {
            y.add(a, b)
        }
    }
    

    ...并打开Y 类和add 方法,以便可以创建和测试模拟(可以通过all open compiler plugin 或直接完成):

    open class Y {
        open fun add(a: Int, b: Int) {}
    }
    

    ...然后测试模拟的Y 类的add 方法只被调用一次(带有尊重的参数)是相当容易的:

    def testYAddWasCalledExactlyOnceWhenCallToXSum() {
        given:
           Y y = Mock()
           def x = new X()
        when:
            x.sum(1, 2, y)
        then:
            1 * y.add(1, 2)
    }
    

    只要确保你的类路径中有byte-buddy

    我还想要一个 Y 的存根,它返回 add >> 10

    有可能,但首先你需要让add函数返回Int

    open class Y {
        open fun add(a: Int, b: Int) : Int { return a + b }
    }
    

    然后你又可以使用 Mock 了:

    def testYAsStub() {
        given:
            Y y = Mock()
            y.add(1, 0) >> 10
        when:
            def sum = y.add(1, 0)
        then:
            sum == 10
    }
    

    【讨论】:

      【解决方案2】:

      你把它命名为:紧耦合!所以在这种情况下答案总是一样的,我想我和这里的其他人一定已经写了几十次了:

      • 您可以重构松散耦合,通过构造函数、setter 或方法参数使依赖项可注入。或者,您可以使用 DI 框架,例如 Guice、Spring、CDI 或类似的。

      • 或者你不要存根依赖,就像 Chrylis 说的那样。但是,您可能不得不忍受调用Y.add(..) 可能产生的任何副作用,这在尝试单独测试X 时可能是不可取的。

      • 或者您使用其他的,而不是 “hacky”工具,例如 PowerMock 或我自己的宝贝 Sarek。尽管这很有效,而且我喜欢我的宝宝,因为它是一个很好玩的玩具,看看它能做什么,我想强调这是最不受欢迎的解决方案,因为它支持和巩固坏的设计而不是使用 TDD 作为设计工具,以引导您开发更可维护、可测试和设计更好的代码。仅当出于某种原因您必须使用具有您无法控制的源代码的第三方类时,才将其用作最后的手段。不过,我假设您在这里控制您的测试类,这通常是这种情况。

      我的建议:去重构!

      【讨论】:

        【解决方案3】:

        你展示的情况中,根本不承认类 Y 的存在,至少在类 X 的上下文中。类 X 对类 Y 的使用是一个不可见的实现细节,并且不是其公共 API 的一部分(在这种情况下,add 只有一种可能的正确实现)。

        【讨论】:

          猜你喜欢
          • 2017-05-09
          • 2011-05-24
          • 2018-11-19
          • 1970-01-01
          • 1970-01-01
          • 2015-05-12
          • 1970-01-01
          • 1970-01-01
          • 2013-12-25
          相关资源
          最近更新 更多