Scala-有没有一种方法可以模拟由同伴对象扩展的特征?

Scala-有没有一种方法可以模拟由同伴对象扩展的特征?,scala,scalatest,scalamock,Scala,Scalatest,Scalamock,在我的小项目中,我正在使用scalatest和scalamock。我创建了一个trait和一个类,以及它的伴生对象 trait A{ def getSomething(arg1) } class B(field1).... object B extends A{ def apply(arg1) = new B(getSomething(arg1)) } 代码运行得很好,但问题发生在测试此代码时。单元测试应该是独立的,因此我应该以某种方式模拟/存根特性A: val fakeA = stu

在我的小项目中,我正在使用scalatest和scalamock。我创建了一个trait和一个类,以及它的伴生对象

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和扩展Blogic的对象B。但接下来呢?

Scala中的对象是表示“世界末日”的单例实例。它们不能被继承、嘲笑(没有黑客)或其他任何东西。您有以下选项:

  • 直接测试对象,即调用
    B。应用(…)
    并将测试结果应用到预期结果
  • 将对象功能提取到traits/class,让它将所有功能混合在一起
  • 第二种解决方案的示例

    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 { }
    
    我不能说你是否有能力和奢侈地把你的物体分解成特征。大多数情况下,这是可行的,没有太多的麻烦,但您的里程可能会有所不同。这种解决方案的另一个优点是根本不需要模拟


    希望它有帮助

    您在这里实际测试的逻辑是什么?谁在使用mocked方法?mocked方法将在我的单元测试中使用。在这里,我想测试apply方法是否创建了有效的对象(即,它将适当的值(由我试图模拟的方法返回)分配给我的B类的适当字段。只需执行
    newB(whateverYourMockWouldReturn)
    ,然后进行测试。