简体   繁体   English

Scala-是否有一种模拟特征的方法,可以通过伴随对象进行扩展?

[英]Scala - Is there a way to mock trait, extended by companion object?

I'm using scalatest along with scalamock for my small project. 我正在将scalatest和scalamock一起用于我的小项目。 I have created a trait and a class, along with its companion object. 我已经创建了一个特征和一个类,以及它的伴随对象。

trait A{
 def getSomething(arg1)
}

class B(field1)....

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

The code works great, but the problem occures while testing this code. 该代码很好用,但是在测试该代码时会出现问题。 Unit test should be independend, therefore I should somehow mock/stub trait A: 单元测试应该是独立的,因此我应该以某种方式模拟/存根特征A:

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

And now... How am I supposed to use this mocked trait in my unit test? 现在...我应该如何在单元测试中使用这个嘲笑的特征? Mocking creates an object (not a type) and with code like this I'm unable to "pass it" to my object (or use with). 模拟创建一个对象(不是类型),并且使用这样的代码,我无法将其“传递”给我的对象(或用于)。 How can I achieve my goal (stub/mock getSomething() inside my B object)? 如何实现我的目标(B对象中的存根/模拟getSomething())? I have tried to split object B into Blogic and B extending Blogic. 我试图将对象B分为Blogic和B扩展Blogic。 But what then? 但是那又怎样呢?

Object in Scala are singleton instances that means "end of the world" . Scala中的Object是单例实例,表示“世界末日” They cannot be inherited, mocked (w/o hacks) or whatever. 它们不能被继承,嘲笑(没有黑客)或其他任何方式。 You have following options: 您有以下选择:

  1. Test your object directly, ie call B.apply(...) and test result to your expected result. 直接测试您的对象,即调用B.apply(...)并将测试结果返回您的预期结果。
  2. Extract the object functionality to traits/classes and let it just mix all the functionality together 将对象功能提取到特征/类中,然后将所有功能混合在一起

Example of 2nd solution 第二解决方案示例

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
}

In you test you can now write: 在测试中,您现在可以编写:

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

I cannot say if you have an ability and luxury to dissect your object into traits. 我不能说您是否有能力和能力将对象分解为特征。 Most of the time it is doable w/o too much hassle, but your mileage may vary. 在大多数情况下,无需太多麻烦就可以做到,但是您的里程可能会有所不同。 Another advantage of such solution is no need for mocks at all. 这种解决方案的另一个优点是完全不需要模拟。

Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM