1
votes

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?

1
Which logic are you actually trying to test here? Who is using the mocked method?Dima
The mocked method would be used in my unit test. Here I would like to test, whether apply method creates valid object (i.e. it assigns proper values (returned by the method Im trying to mock) to proper fields of my B class.DorianOlympia
Just do new B(whateverYourMockWouldReturn) then, and test that.Dima

1 Answers

2
votes

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:

  1. Test your object directly, i.e. call B.apply(...) and test result to your expected result.
  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