PowerMock not able to resolve ambiguous reference - scala

I am trying to test a simple application in Scala , and test it with PowerMock.
Below is my code
Service.scala
trait Service {
def getName(): String
def start(): Int
}
ServiceListener.scala
trait ServiceListener {
def onSuccess(service: Service): Unit
def onFailure(service: Service): Unit
}
SomeSystem.scala
import java.util
import java.util.List
import SomeSystem._
import scala.collection.JavaConversions._
object SomeSystem {
def notifyServiceListener(serviceListener: ServiceListener, service: Service, success: Boolean) {
if (serviceListener != null) {
if (success) {
serviceListener.onSuccess(service)
} else {
serviceListener.onFailure(service)
}
}
}
def startServiceStaticWay(service: Service): Int = {
val returnCode = service.start()
returnCode
}
}
class SomeSystem {
private val services: List[Service] = new util.ArrayList[Service]()
private var serviceListener: ServiceListener = _
private val events: List[String] = new util.ArrayList[String]()
def start() {
for (service <- services) {
val something = startServiceStaticWay(service)
val success = something > 0
notifyServiceListener(serviceListener, service, success)
addEvent(service, success)
}
}
private def addEvent(service: Service, success: Boolean) {
events.add(getEvent(service.getName, success))
}
private def getEvent(serviceName: String, success: Boolean): String = {
serviceName + (if (success) "started" else "failed")
}
def add(someService: Service) {
services.add(someService)
}
def setServiceListener(serviceListener: ServiceListener) {
this.serviceListener = serviceListener
}
}
I am trying to unit test SomeSystem.scala as below
import {ServiceListener, SomeSystem, Service}
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.powermock.api.mockito.PowerMockito
import org.powermock.modules.junit4.PowerMockRunner
//remove if not needed
import scala.collection.JavaConversions._
#RunWith(classOf[PowerMockRunner])
class PowerMockitoIntegrationTest {
private var service: Service = _
private var system: SomeSystem = _
private var serviceListener: ServiceListener = _
#Before
def setupMock() {
service = Mockito.mock(classOf[Service])
serviceListener = Mockito.mock(classOf[ServiceListener])
system = Mockito.spy(new SomeSystem())
system.add(service)
system.setServiceListener(serviceListener)
}
#Test
def startSystem() {
p("Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful")
PowerMockito.when(service.start()).thenReturn(1)
p("Start the system, should start the services in turn")
system.start()
p("Verify using Mockito that service started successfuly")
Mockito.verify(serviceListener).onSuccess(service)
p("Verifed. Service started successfully")
}
private def p(s: String) {
println(s)
}
}
Unfortunately I am getting the below compilation error , I am confused why it is appearing and any way we could do get rid of it.
[ERROR] C:\IntellJWorkspace\PowerMockProblem\src\test\scala\PowerMockitoIntegrationTest.scala:29: error: ambiguous reference to overloaded definition,
[ERROR] both method when in object PowerMockito of type [T](x$1: T)org.mockito.stubbing.OngoingStubbing[T]
[ERROR] and method when in object PowerMockito of type [T](x$1: Any, x$2: Object*)org.mockito.stubbing.OngoingStubbing[T]
[ERROR] match argument types (Int)
[ERROR] PowerMockito.when(service.start()).thenReturn(1)

When we use PowerMockito in scala, we face with overloading problem. Scala compiler will not be able to identify overloaded methods correctly and throws error saying ambiguous definition.
So if you want to use PowerMockito, mention your statement something as below, e.g.:
PowerMockito.when(SomeClass.staticmethod(someObject, someObject), Seq.empty[Object])
.thenReturn(expectedXml, Seq.empty[Object])

Related

Get PrepareStament Variable in Scala

I would like to make the prepareStatement serializable
A preparedStatement is not serializable. I have to build a serializable structure that wraps the call and the parameters to control the construction of the said statement during the deserialization
Here are the classes I created to wrap the PrepareStament
import java.sql._
import java.sql.SQLException
import java.util
import java.util.Collections
import avro.shaded.com.google.common.collect.ImmutableMap
import scala.collection.immutable.HashMap
import scala.collection.mutable
class WrappedConnection(var delegate: Connection) extends Serializable {
def prepareStatement(sql: String): WrappedPreparedStatement = {
val ps = delegate.prepareStatement(sql)
new WrappedPreparedStatement(sql, ps)
}
// delegate all Connection methods to the delegate
}
class WrappedPreparedStatement(var sql: String, var delegate: PreparedStatement) extends Serializable {
private var parameters: mutable.Map[Integer, Object] = mutable.Map.empty[Integer, Object]
override def toString: String = sql
def apply( delegateVar: PreparedStatement) {
delegate = delegateVar
parameters = mutable.Map.empty[Integer, Object]
}
def getParameters = parameters
// TODO: many methods to delegate
#throws[SQLException]
def setString(parameterIndex: Int, x: String): Unit = {
delegate.setString(parameterIndex, x)
parameters.put(parameterIndex, x)
}
#throws[SQLException]
def executeQuery = { // perhaps you might want to do some logging here?
delegate.executeQuery
}
// delegate all PreparedStatement methods to the delegate
}
object WrappedConnection {
def apply(delegate: Connection): WrappedConnection = new WrappedConnection(delegate)
}
This is the test code
val connection = MsSqlUtils.createConnectionFactory(config)
val conn = connection()
val wrapperConn = WrappedConnection(conn)
val statement = wrapperConn.prepareStatement("select * from users")
Currently, my problem is to access the variables of my prepareStatement object and create get functions that will return them.
When I talk about variables I talk about the one shown in the picture below not the one in the querie
Anyone know how to access these variables?

Specs2 with Scaldi - wrong implicit injector being invoked

I'm trying to run a test with scaldi and specs2. In the test I need to override a StringManipulator function that uses an injected ProxyManipulator. The ProxyManipulator takes a string and returns its upper case in a Future. The replacement manipulator in the test returns a Future("Test Message").
Here is the StringManipulator class where the injection occurs:
class StringManipulator {
def manip (str : String) (implicit inj: Injector) : String = {
val prox = inject[ProxyManipulator]
Await.result(prox.manipulate(str), 1 second)
}
}
I'm using a package.object that contains the implicit injector:
import modules.MyModule
package object controllers {
implicit val appModule = new MyModule
}
And here is the specs2 test with the new binding:
#RunWith(classOf[JUnitRunner])
class StringManipScaldiSpec extends Specification {
class TestModule extends Module {
bind [ProxyManipulator] to new ProxyManipulator {
override def manipulate(name: String) = Future("Test Message")
}
}
"Application" should {
"do something" in {
val myTestModule = new TestModule
val str = "my string"
val stringMan = new StringManipulator() //(myTestModule)
stringMan.manip(str)(myTestModule) === "Test Message"
}
}
}
The problem is that when the test runs the class StringManipulator is still using the original Proxy Manipulator instead of the one passed in the TestModule. Any ideas?

Scala by Example: spawn function in scala 2.11.7

I'm trying implement section 17.9 Workers in Scala by Example book with Scala version 2.11.7.
Import statements:
import scala.concurrent._, scala.concurrent.ops._
was error "ops not is member of scala.concurrent". I did google and known that concurrent.ops is deprecated and rather by future, change import statement to:
import scala.concurrent._, scala.concurrent.Future._
Entire class source:
import scala.concurrent._
import scala.concurrent.Future._
class ComputeServer(n: Int) {
private abstract class Job {
type T
def task: T
def res(x: T)
}
private val openJobs = new Channel[Job]()
private def processor(i: Int) {
while(true) {
val job = openJobs.read
job.res(job.task)
}
}
def future[A](p: => A): () => A = {
val reply = new SyncVar[A]()
openJobs.write{
new Job{
type T = A
def task = p
def res(x: A) = reply.put(x)
}
}
() => reply.get
}
spawn(replicate(0, n){processor})
}
But occurs errors in line: spawn(replicate(0, n){processor})
not found: value spawn
not found: value replicate
missing arguments for method processor in class ComputeServer; follow this method with `_' if you want to treat it as a partially applied function
What're spawn, replicate, processor function in version 2.11.7?
one can create method spawn like this:
def spawn(p: => Unit) {
val t = new Thread() { override def run() = p }
t.start()
}

Custom Slick Codegen generate mapped case classes outside the `${container} trait`?

Can Slick Codegen generate all the mapped case classes outside of the ${container} trait
, so that they don't inherit its type? Maybe in another file altogether i.e. Models.scala?
// SuppliersRowsDAA.scala
import persistence.Tables
object SuppliersRowsDAA {
case class Save(sup: Tables.SuppliersRow)
}
I get this compilation error:
[error] /app/src/main/scala/persistence/dal/SuppliersDAA.scala:5: type mismatch;
[error] found : persistence.Tables.SuppliersRow
[error] required: SuppliersDAA.this.SuppliersRow
[error] case Save(sup) ⇒ sender ! db.run(Suppliers += sup)
Using Tables#SuppliersRow import gives the same error.
If I manually cut & paste the SuppliersRow case class outside of the auto-generated trait Tables it works!
....
trait Tables {
....
}
case class SuppliersRow(id: Int, userId: Int, name: String)
//EOF
Appending the original docWithCode of EntityType to super.packageCode():
import slick.codegen.SourceCodeGenerator
import slick.model.Model
import scala.collection.mutable
class CustomizedCodeGenerator(model: Model) extends SourceCodeGenerator(model) {
val models = new mutable.MutableList[String]
override def packageCode(profile: String, pkg: String, container: String, parentType: Option[String]): String = {
super.packageCode(profile, pkg, container, parentType) + "\n" + outsideCode
}
def outsideCode = s"${indent(models.mkString("\n"))}"
override def Table = new Table(_) {
override def EntityType = new EntityTypeDef {
override def docWithCode: String = {
models += super.docWithCode.toString + "\n"
""
}
}
}
}

Scala Implicit Type Conversion of Classes with Type Parameters

I'm trying to add functionality to the scala.collection.Iterable trait, more specifically, a printerate function that iterates through the elements and prints them out (to the console if there are no parameters, otherwise to the outputstream param). I'm using a predefined extension method that I created for object, printSelf(). However, this is causing an compiler error, 'Value printSelf is not a member of type parameter Object.' I'd also like to have this an a separate file so that it's easy for me to use between several projects and applications.
Here's my current code for my conversion file:
import java.io.OutputStream
import scala.collection.Iterable
package conversion{
class Convert {
implicit def object2SuperObject(o:Object) = new ConvertObject(o)
implicit def iterable2SuperIterable[Object](i:Iterable[Object]) = new ConvertIterable[Object](i)
}
class ConvertObject(o:Object){
def printSelf(){
println(o.toString())
}
def printSelf(os:OutputStream){
os.write(o.toString().getBytes())
}
}
class ConvertIterable[Object](i:Iterable[Object]){
def printerate(){
i.foreach {x => x.printSelf() }
}
def printerate(os:OutputStream){
i.foreach { x => x.printSelf(os) }
}
}
}
I'm also getting a similar error in the code that's trying to test this out, 'value printerate is not a member of scala.collection.immutable.Range':
import conversion.Convert
package test {
object program extends App {
new testObj(10) test
}
class testObj(i: Integer) {
def test(){
val range = 0.until(i)
0.until(i).printerate()
}
}
}
What's wrong with the way that I'm approaching this type conversion?
Several things in fact:
Convert should be an object, not a class.
You use Object instead of Any
You use Object as a generic type identifier, instead of the much less confusing T.
You do not import the implicit definitions (it's not enough to import the object itself).
This should work:
package conversion {
object Convert {
implicit def object2SuperObject(o: Any) = new ConvertObject(o)
implicit def iterable2SuperIterable[T](i:Iterable[T]) = new ConvertIterable[T](i)
}
class ConvertObject(o: Any){
def printSelf(){
println(o.toString())
}
def printSelf(os:OutputStream){
os.write(o.toString().getBytes())
}
}
class ConvertIterable[T](i:Iterable[T]){
import Convert.object2SuperObject
def printerate(){
i.foreach {x => x.printSelf() }
}
def printerate(os:OutputStream){
i.foreach { x => x.printSelf(os) }
}
}
}
import conversion.Convert._
Second file:
package test {
object program extends App {
new testObj(10) test
}
class testObj(i: Integer) {
def test(){
val range = 0.until(i)
0.until(i).printerate()
}
}
}