Scala - 有没有办法模拟特征,由伴侣对象扩展?

时间:2016-02-20 12:58:07

标签: scala scalatest scalamock

我正在使用scalatest和scalamock进行我的小项目。我创建了一个特征和一个类,以及它的伴随对象。

trait A{
 def getSomething(arg1)
}

class B(field1)....

object B extends A{
 def apply(arg1) = new B(getSomething(arg1))
}

代码运行良好,但在测试此代码时出现问题。单元测试应该是独立的,因此我应该以某种方式模拟/存根特性A:

val fakeA = stub[A]    
(fakeA.getSomething _).when(arg).returns(res)

现在......我应该如何在单元测试中使用这个模拟特征?模拟会创建一个对象(不是类型),并且使用这样的代码,我无法将其“传递”到我的对象(或与之一起使用)。如何实现我的目标(我的B对象中的stub / mock getSomething())?我试图将对象B拆分为Blogic,B扩展为Blogic。那么呢?

1 个答案:

答案 0 :(得分:0)

Scala中的对象是单例实例,意味着"世界末日" 。他们不能被继承,嘲笑(没有黑客)或其他什么。您有以下选择:

  1. 直接测试您的对象,即调用B.apply(...)并测试结果为您的预期结果。
  2. 将对象功能提取到特征/类,并让它将所有功能混合在一起
  3. 第二种解决方案的例子

    trait A{
      def getSomething(arg1: Int): Int = ???
    }
    
    trait BFactoryUsingA { self: A => // This says that it needs/requires A
      def apply(arg1: Int) = new B(getSomething(arg1))
    }
    
    class B(field1: Int) {}
    
    object B extends BFactoryUsingA with A {
      // No methods or those which have nothing to do with traits A and BFactoryUsingA hierarchy and composition
    }
    

    在你测试中你现在可以写:

    // Instance as anonymous mixin of traits containing logic
    val instanceUnderTest = new BFactoryUnsingA with A { }
    

    我不能说你是否有能力和奢侈地将你的对象分解成特征。大多数情况下,它是可行的,没有太多的麻烦,但你的里程可能会有所不同。这种解决方案的另一个优点是根本不需要模拟。

    希望有所帮助