Reputation: 851
I'm using scalatest along with scalamock for my small project. 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:
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)? I have tried to split object B into Blogic and B extending Blogic. But what then?
Upvotes: 1
Views: 3103
Reputation: 1541
Object in Scala are singleton instances that means "end of the world". They cannot be inherited, mocked (w/o hacks) or whatever. You have following options:
B.apply(...)
and test result to your expected result.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
Upvotes: 2