2

Using ScalaTest, I want to replace a function implementation in a test case. My use case:

object Module {
  private def currentYear() = DateTime.now().year.get

  def doSomething(): Unit = {
    val year = currentYear()
    // do something with the year
  }
}

I want to write a unit test testing Module.doSomething, but I don't want this test case to depend on the actual year the test is run in.

In dynamic languages I often used a construct that can replace a functions implementation to return a fixed value.

I'd like my test case to change the implementation of Module.currentYear to always return 2014, no matter what the actual year is.

I found several mocking libraries (Mockito, ScalaMock, ...), but they all only could create new mock objects. None of them seemed to be able to replace the implementation of a method.

Is there a way to do that? If not, how could I test code like that while not being dependent on the year the test is run in?

samthebest
  • 30,803
  • 25
  • 102
  • 142
Heinzi
  • 5,793
  • 4
  • 40
  • 69

2 Answers2

1

One way would be to just make do_something_with_the_year accessible to your test case (make it package protected for example). This is also nice because it separates looking up dependencies and actually using them.

Another way would be to put your logic in a trait, make the currentYear method protected and let the object be an instance of that trait. That way you could just create a custom object out of the trait it in a test and wouldn't need any mock library.

johanandren
  • 11,249
  • 1
  • 25
  • 30
  • both valid solutions, but I don't like the design. Users of Module don't need to know Module is doing something with a year. Dynamic languages allow stubbing out functions in this way. Isn't there a way in scala to do so? – Heinzi Aug 03 '14 at 08:39
  • That would be the public interface, part of the object, that it was implemented in a trait would be a package private implementation detail, so the users would not have to know. If you really want to mimic dynamic languages then look at samthebests answer about scalamock. – johanandren Aug 05 '14 at 08:16
1

ScalaMock can mock singleton objects it says it right here: http://paulbutcher.com/2011/11/06/scalamock-step-by-step/

As well as traits (interfaces) and functions, it can also mock:

Classes

Singleton and companion objects (static methods) ...

samthebest
  • 30,803
  • 25
  • 102
  • 142