Mockito scala Ambiguous reference to overloaded definition - scala

I am trying to mock resultset in scala using mockito like below
val resultset = mock[java.util.ResultSet]
However when i try to mock getString method like below i am getting ambiguous reference to overloaded definition error as getString can accept either string or int
(resultset.getString _).expects(any[String]).returns("test")
what could be the issue?

This is an known issue with Java/Scala interop, please migrate to mockito-scala which solves it.
Then you can use the examples amer has posted (just use the methods from the traits and not from the Mockito class) or you can try the scala syntax
resultset.getString(*) returns "test"

Try something like this maybe:
Mockito.when(resultset.getString(any())) thenReturn "test"
or
Mockito.when(resultset.getString(anyString())) thenReturn "test"

Related

Scala: foreachPartition passing Object type instead of Iterator[Row] to method

I'm new to Scala. I'm trying to use foreachPartition over a partitioned dataframe. I'm trying to call a method (makePreviewApiCall) inside foreachPartition.
Here is the signature of the method being called :
def makePreviewApiCall(
partitioned_df:Iterator[Row],
header_df:DataFrame,
sqlcontext:SQLContext): Unit = {...}
I'm trying to call the above method from foreachpartition as below:
partitioned_df.foreachPartition(rddpartition => makePreviewApiCall(rddpartition, header_df, sqlcontext))
I'm getting the build error as below:
found : Object
required: Iterator[org.apache.spark.sql.Row]
one error found
What is wrong here? rddpartition is of type Iterator[Row]. Why is it being treated as an Object?
Looks like existing two methods (Scala specific vs Java specific) conflict with Scala 2.12 whereas Scala 2.11 didn't.
You can explicitly mention the type in lambda like
.foreachPartition((part: Iterator[Row]) => {

Scala 'this' and 'self' not working in simple App

New to scala (using version 2.12.1) obviously from the title. I'm writing my first app in IntelliJ. I've read about the Scala equivalent in Java to this. I've tried this, self, classOf[] and IntelliJ is complaining and the code is not compiling even if I ignore IntelliJ. Here's what I have:
import ch.qos.logback.classic.Logger
object Main extends App {
val logger = Logger[Main]
}
Logger package is importing correctly in SBT. However it cannot resolve the symbol Main. I tried sticking it in a package to make it less ubiquitous and then doing something like Logger[me.justin.Main] but that also doesn't work.
I also thought maybe extending App was causing some problems but I think that's fixed in the scala version I'm using? Maybe it's not even applicable?
I'm all Googled out. Help please!
You're getting tripped up by how Scala's objects work. Let's say we had a class Foo and a companion object for same:
class Foo
object Foo
If we wanted a logger for the class, we'd do the obvious thing:
val logger = Logger[Foo] // `Foo` here is the type of the class.
But what if we wanted to refer to the type of the object? We have to disambiguate from the type of the class. The answer is to use the special type member on the object:
val logger = Logger[Foo.type] // `Foo.type` here is the type of the object.
So in your case:
val logger = Logger[Main.type]

Using Mockito & Guice to test interfaces with generics in Scala

I am new to Scala, and I'm running into this problem when I'm trying to unit test some of my interfaces.
I have an InputService trait with method
def poll(parameters: HashMap[String, String]): Option[T]
where T is generic, so InputService has a type parameter [T].
In my module, I have
val inputService: InputService[String] = mock(classOf[InputService[String]])
bind[InputService[String]].toInstance(inputService)
and in my InputServiceTest, I have
var inputService: InputService[String] = _
before {
inputService = Guice.createInjector(new MockWatcherModule).getInstance(classOf[InputService[String]])
}
But the issue is when I run it, it gives me this error
Exception encountered when invoking run on a nested suite - Guice configuration errors:
1) No implementation for services.InputService was bound.
while locating services.InputService
I think it's because it's looking for services.InputService to bound, but it only has services.InputService[String]. However, when I just use InputService instead of InputService[String], I get the error Trait missing Type Parameter.
Any suggestions?
EDIT:
Turns out that I can use typeLiteral from scala-guice and KeyExtensions to solve my issue. Thanks Tavian!
Due to type erasure, in the getInstance(classOf[InputService[String]]) call, you're just passing InputService.class. You need to pass a TypeLiteral instead to encode the generic type information. From a quick Google it looks like
import net.codingwell.scalaguice._
import net.codingwell.scalaguice.InjectorExtensions._
Guice.createInjector(new MockWatcherModule).instance[InputService[String]]
will work.

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.

Type matching unparameterised Java List in Scala

I'm trying to set a mock expectation in a test in Scala. The mock is on the Hibernate Query object. It has the method:
List list() throws HibernateException;
The List is not parameterised.
When I try to mock this I can't get the types right. E.g.
when(query.list).thenReturn(new ArrayList)
when(query.list).thenReturn(new ArrayList[Any])
// and other variations
Report:
overloaded method value thenReturn with alternatives:
(java.util.List[?0],<repeated...>[java.util.List[?0]])org.mockito.stubbing.OngoingStubbing[java.util.List[?0]] <and>
(java.util.List[?0])org.mockito.stubbing.OngoingStubbing[java.util.List[?0]]
cannot be applied to (java.util.ArrayList[java.lang.Object])
What should my Scala mock expectation look like?
You can use an asInstanceOf cast and write:
when(query.list.asInstanceOf[ArrayList[Any]]).thenReturn(new ArrayList[Any])