Mock for comprehension in scala - scala

I have this piece of code
for (element <- table.find;
Right(info) = exceptionManager(mapper.getInfoFromDbObject(element)))
yield info
and I would like to unit test it. I want to mock table.find in order to return a sequence of element that I want. I have tried mocking hasNext() and next() methods of Iterator interface but it seems it is not working. Which is the method to mock a for comprehension?

Each for comprehension is translated to map, flatMap, filter method calls. So you should mock at least them.
You can find more information here (for example):
http://www.lambdascale.com/2010/12/the-adventures-of-a-java-developer-in-monadland/
And of course you will find deep explanation in Programming in Scala book.
Edit
But as Dave Griffith said, you can just initialize new Iterator yourself. Here is an example that uses Mockito and ScalaTest:
val table = mock[TableClass]
when(table find) thenReturn Iterator(new ModelObject(1), new ModelObject(2))
Edit 1
As Daniel noticed, filter method is now deprecated in for comprehensions. Instead you should use withFilter. For more information you can look in this thread:
http://scala-programming-language.1934581.n4.nabble.com/Rethinking-filter-td2009215.html#a2009218
and this related SO question:
guide to move from filter to withFilter?

In theory, you should mock the "map" method, but you're probably better off simply having table.find return one of the predefined collection types.

Related

Scala boilerplate: lack of common superclass of Iterable and ParIterable

Why is Scala designed with the following irritating form of boilerplate?
It would be convenient to write
def doStuffWithInts(ints: BaseIterable[Int]): Unit = ints foreach doStuffWithInt
for a common superclass BaseIterable of Iterable and ParIterable so that we can write both
val sequentialInts: Vector[Int] = getSomeHugeVector()
doStuffWithInts(sequentialInts)
and
val parInts: ParVector[Int] = getSomeHugeParVector()
doStuffWithInts(parInts)
Yet Scala forces us to copy and paste our doStuff method, once for Iterable and once for ParIterable. Why does Scala thrust such boilerplate on us by failing to have a common superclass BaseIterator of both Iterator and ParIterator?
You can use IterableOnce but that would force you to get an Iterator which is always sequential.
This is a conscious decision from the maintainers, you can read all the related discussions by starting here: https://github.com/scala/scala-parallel-collections/issues/101
The TL;DR; is that the maintainers agree that it is a bad idea to provide an abstraction between two; mainly because parallel collections should not be used as general collections but rather as localized optimizations. Also, the point out how easy it would be to introduce errors if you could abstract over the two (as was the case in 2.12).
Now, if you insist you want to abstract over the two, you may create your own typeclass.
Finally, I may suggest looking at using Future.traverse instead of parallel collections.

How to find max date from stream in scala using CompareTo?

I am new to Scala and trying to explore how I can use Java functionalities with Scala.
I am having stream of LocalDate which is a Java class and I am trying to find maximum date out of my list.
var processedResult : Stream[LocalDate] =List(javaList)
.toStream
.map { s => {
//some processing
LocalDate.parse(str, formatter)
}
}
I know we can do easily by using .compare() and .compareTo() in Java but I am not sure how do I use the same thing over here.
Also, I have no idea how Ordering works in Scala when it comes to sorting.
Can anyone suggest how can get this done?
First of all, a lot of minor details that I will point out since it seems you are pretty new to the language and I expect those to help you with your learning path.
First, avoid var at all costs, especially when learning.
While mutability has its place and is not always wrong, forcing you to avoid it while learning will help you. Particularly, avoid it when it doesn't provide any value; like in this case.
Second, this List(javaList) doesn't do what you think it does. It creates a single element Scala List whose unique element is a Java List. What you probably want is to transform that Java List into a Scala one, for that you can use the CollectionConverters.
import scala.jdk.CollectionConverters._ // This works if you are in 2.13
// if you are in 2.12 or lower use: import scala.collection.JavaConverters._
val scalaList = javaList.asScala.toList
Third, not sure why you want to use a Scala Stream, a Stream is for infinite or very large collections where you want all the transformations to be made lazily and only produce elements as they are consumed (also, btw, it was deprecated in 2.13 in favour of LazyList).
Maybe, you are confused because in Java you need a "Stream" to apply functional operations like map? If so, note that in Scala all collections provide the same rich API.
Fourth, Ordering is a Typeclass which is a functional pattern for Polymorphism. On its own, this is a very broad question so I won't answer it here, but I hope the two links provide insight.
The TL;DR; is simple, it is just that an Ordering for a type T knows how to order (sort) elements of type T. Thus operations like max will work for any collection of any type if, and only if, the compiler can prove the existence of an Ordering for that type if it can then it will pass such value implicitly to the method call for you; again the implicits topic is very broad and deserves its own question.
Now for your particular question, you can just call max or maxOption in the List or Stream and that is all.
Note that max will throw if the List is empty, whereas maxOption returns an Option which will be empty (None) for an empty input; idiomatic Scala favour the latter over the former.
If you really want to use compareTo then you can provide your own Ordering.
scalaList.maxOption(Ordering.fromLessThan[LocalDate]((d1, d2) => d1.compareTo(d2) < 0))
Ordering[A] is a type class which defines how to compare 2 elements of type A. So to compare LocalDates you need Ordering[LocalDate] instance.
LocalDate extends Comparable in Java and Scala conveniently provides instances for Comparables so when you invoke:
Ordering[java.time.LocalDate]
in REPL you'll see that Scala is able to provide you the instance without you needing to do anything (you could take a look at the list of methods provided by this typeclass).
Since you have and Ordering in implicit scope which types matches the Stream's type (e.g. Stream[LocalDate] needs Ordering[LocalDate]) you can call .max method... and that's it.
val processedResult : Stream[LocalDate] = ...
val newestDate: LocalDate = processedResult.max

How can I allow the caller to call method of field of case class?

I am not sure the keywords for this pattern, sorry if the question is not clear.
If you have:
case class MyFancyWrapper(
somethingElse: Any,
heavyComplexObject: CrazyThing
)
val w = MyFancyWrapper(???, complexThing)
I want to be able to call w.method with the method coming from complexThing. I tried to extends CrazyThing but it is a trait and I don't want to implement all the method that would be very tedious. I also don't want to have to do:
def method1 = heavyComplexObject.method1
...
for all of them.
Any solution ?
Thanks.
You can do this with macros but I agree with Luis that this is an overkill. Macros are intended to repetitive boring things, not one time boring things. Also this is not as trivial as it sounds, because you probably don't want to pass through all the methods (you probably still want your own hashCode and equals). Finally macros have bad IDE support so most probably no auto-completion for all those methods. On the other hand if you do use a good IDE (like IDEA) there is most probably an action like "Delegate methods" that will generate most of the code for you. You still will have to change the return type from Unit to MyFancyWrapper and add returning this at the end of each method but this can easily be done with mass replace operations (hint: replace "}" with "this }" and the automatically re-formatting code should do the trick)
Here are some screenshots of the process from JetBrains IDEA:
You can use an implicit conversion to make all the methods of heavyComplexThing directly available on MyFancyWrapper:
implicit def toHeavy(fancy: MyFancyWrapper): CrazyThing = fancy.heavyComplexObject
This needs to be in scope when the method is called.
In the comments you indicate that you want to return this so that you can chain multiple calls on the same object:
w.method1.method2.method3
Don't do this
While this is a common pattern in non-functional languages, it is bad practice is Scala for two reasons:
This pattern inherently relies on side-effects, which is the antithesis of functional programming.
It is confusing, because in Scala chaining calls in this way is used to implement a data pipeline, where the output of one function is passed as the input to the next.
It is much clearer to write separate statements so that it is obvious that the methods are being called on the same object:
w.method1()
w.method2()
w.method3()
(It is also conventional to use () when calling methods with side effects)

How to iterate through lazy iterable in scala? from stanford-tmt

Scala newbie here,
I'm using stanford's topic modelling toolkit
and it has a lazy iterable of type LazyIterable[(String, Array[Double])]
How should i iterate through all the elements in this iterable say it to print all these values?
I tried doing this by
while(it.hasNext){
System.out.println(it.next())
}
Gives an error
error: value next is not a member of scalanlp.collection.LazyIterable[(String, Array[Double])]
This is the API source -> iterable_name ->
InferCVB0DocumentTopicDistributions in
http://nlp.stanford.edu/software/tmt/tmt-0.4/api/edu/stanford/nlp/tmt/stage/package.html
Based on its source code, I can see that the LazyIterable implements the standard Scala Iterable interface, which means you have access to all the standard higher-order functions that all Scala collections implement - such as map, flatMap, filter, etc.
The one you will be interested in for printing all the values is foreach. So try this (no need for the while-loop):
it.foreach(println)
Seems like method invocation problem, just check the source code of LazyIterable, look at line 46
override def iterator : Iterator[A]
when you get an instance of LazyIterable, invoke iterator method, then you can do what you want.

Searching inside scala 2.10 ASTs

What's the best way to recursively search for an element in scala 2.10 ASTs?
The trees might be a result of power.trees(code) or mirror.mkToolBox().parseExpr(code)
Edit. In 2.10.0-RC1 parseExpr has been renamed to parse.
The concrete use-case that I have is extracting the code of a method from a given class/object code by method name,
but I assume that the question would be more relevant for others if formulated in a more generic way.
Maybe you should have a look at https://github.com/scala/scala/blob/2.10.x/src/reflect/scala/reflect/api/Trees.scala#L606, especially at the classes Traverser, Transformer and the methods for substitution (Tree.substituteSymbols, Tree.substituteTypes or Tree.substituteThis). If you want to extract a method from a tree, you can use a Traverser and override the traverse method. In the traverse method, you check whether the node matches the method you want. If so, you are done. If not, you call super.traverse.