Override a method in a mock object - scala

I need to write a unit test in which one of the dependencies of the tested object will be mocked. In that mocked object I would like to override one function (I do not care about the other functions at all).
What I need to do, is to provide a completely new implementation of that function. I am not particularly happy with providing mockito-style when / thenResult pairs for each potential input, i.e. I do not want to write:
when(mock.foo(5)).thenResult(3)
when(mock.foo(7)).thenResult(121)
...
I would rather like to write something like:
mock.foo = (a: Int) => if (a == 5) 3 else ...
Which mocking framework should I choose to substitute the whole implementation of a function in an easy way?

You don't need a mocking framework at all if you're only overriding one method and want to do it by actually defining the method.
If it's a class, just extend your class, override the method and inject your extension.
If it's an object or a final class of course you can't extend, but then you wouldn't be able to mock with many frameworks either, or inject an alternate easily.

http://scalamock.org/user-guide/advanced_topics/
See "onCall" method
(fooMock.increment _) expects(*) onCall { arg: Int => arg + 1}

Related

Quick Documentation For Scala Apply Constructor Pattern in IntelliJ IDE

I am wondering if there is a way to get the quick documentation in IntelliJ to work for the class construction pattern many scala developers use below.
SomeClass(Param1,Parma2)
instead of
new SomeClass(param1,Param2)
The direct constructor call made with new obviously works but many scala devs use apply to construct objects. When that pattern is used the Intelij documentation look up fails to find any information on the class.
I don't know if there are documents in IntelliJ per se. However, the pattern is fairly easy to explain.
There's a pattern in Java code for having static factory methods (this is a specialization of the Gang of Four Factory Method Pattern), often along the lines of (translated to Scala-ish):
object Foo {
def barInstance(args...): Bar = ???
}
The main benefit of doing this is that the factory controls object instantiation, in particular:
the particular runtime class to instantiate, possibly based on the arguments to the factory. For example, the generic immutable collections in Scala have factory methods which may create optimized small collections if they're created with a sufficiently small amount of contents. An example of this is a sequence of length 1 can be implemented with basically no overhead with a single field referring to the object and a lookup that checks if the offset is 0 and either throws or returns its sole field.
whether an instance is created. One can cache arguments to the factory and memoize or "hashcons" the created objects, or precreate the most common instances and hand them out repeatedly.
A further benefit is that the factory is a function, while new is an operator, which allows the factory to be passed around:
class Foo(x: Int)
object Foo {
def instance(x: Int) = new Foo(x)
}
Seq(1, 2, 3).map(x => Foo(x)) // results in Seq(Foo(1), Foo(2), Foo(3))
In Scala, this is combined with the fact that the language allows any object which defines an apply method to be used syntactically as a function (even if it doesn't extend Function, which would allow the object to be passed around as if it's a function) and with the "companion object" to a class (which incorporates the things that in Java would be static in the class) to get something like:
class Foo(constructor_args...)
object Foo {
def apply(args...): Foo = ???
}
Which can be used like:
Foo(...)
For a case class, the Scala compiler automatically generates a companion object with certain behaviors, one of which is an apply with the same arguments as the constructor (other behaviors include contract-obeying hashCode and equals as well as an unapply method to allow for pattern matching).

Scala Argument Capture of External Class

So I want to check arguments that I send to an external class that I do not control. The external class is assumed tested, I simply want to test if I passed it the right parameters. I have tried some combination of ArgumentCaptor etc, but not much luck
import org.ABC.ExternalClass
case class Foo(i:Int, j: Int...) {
val EC = CreateExternalClass()
def CreateExternalClass(): ExternalClass = {
new ExternalClass (i, j, ....many parameters)
}
}
I think you are getting things wrong here: you can only use an ArgumentCaptor on calls to mocked objects. You can't use them to "intercept" arbitrary calls between all kinds of objects.
Meaning: you could only use an ArgumentCaptor if you would be using a mocked ExternalClass object. But then you would not need to capture, as you probably could do simply method call argument verification.
But of course, you can't use Mockito to mock that call to new in your production class. The options you have:
Turn to PowerMockito or JMockit; frameworks that allow to mock calls to new. Not recommended.
Rework your production code to not do that call to new. Probably not helpful here; as this class might already be a wrapper around that external class
Go for checking on the created object: check if you could use getter methods to simply query the newly created object to have the values that you expect to show up inside

Use mocked function return value in real function call

Is it possible to use a mocked function inside a real function call? Both functions are in the same object. So for example, if I have
obj A {
def mockThis(value: Int): Int = {
value*5
}
def realFuncIWantToTest(value: Int): Int = {
val v = mockThis(value)
v
}
}
Obviously this is an extremely simple case and this isn't what my code is doing (v is actually a complicated object). Essentially I want realFuncIWantToTest to use the mocked function return value that I define.
Thanks!
You might be able to do this using Mockito's spies; see here for an example on that.
Spies basically work by having that spy wrapping around a real object of your class under test.
But one word here: even when it is possible, please consider changing your design instead. This "partial mocking" is often a good indication that your class is violating the single responsibility principle. Meaning: a class should be responsible for "one" thing. But the idea that you can / have to partially mock things within your class indicates that your class is responsible for at least two, somehow disconnect aspects.
In that sense: the better approach would be that mockThis() would be a call on another object; which could be inserted via dependency injection into this class.
Long story short: at least on a Java level your idea should work fine (where I have certain doubts that Mockito will work nicely with your scala objects) from a technical perspective; but from a conceptual point point; you should rather avoid doing it this way.

Use `#annotation.varargs` on constructors

I want to declare a class like this:
class StringSetCreate(val s: String*) {
// ...
}
and call that in Java. The problem is that the constructor is of type
public StringSetCreate(scala.collection.Seq)
So in java, you need to fiddle around with the scala sequences which is ugly.
I know that there is the #annotation.varargs annotation which, if used on a method, generates a second method which takes the java varargs.
This annotation does not work on constructors, at least I don't know where to put it. I found a Scala Issue SI-8383 which reports this problem. As far as I understand there is no solution currently. Is this right? Are there any workarounds? Can I somehow define that second constructor by hand?
The bug is already filed as https://issues.scala-lang.org/browse/SI-8383 .
For a workaround I'd recommend using a factory method (perhaps on the companion object), where #varargs should work:
object StringSetCreate {
#varargs def build(s: String*) = new StringSetCreate(s: _*)
}
Then in Java you call StringSetCreate.build("a", "b") rather than using new.

Scala Testing: Replace function implementation

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?
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.
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) ...