Cannot create an instance of an abstract class (Random) - random

I am trying to learn Kotlin so I was following a tutorial on internet where instructor wrote a code which worked fine in with them but it gives error to me.
This is the error
Error:(26, 17) Kotlin: Cannot create an instance of an abstract class
import kotlin.random.Random
fun main(args: Array<String>) {
feedTheFish()
}
fun feedTheFish() {
val day = randomDay()
val food = "pellets"
print("Today is ${day} and the fish eat ${food}")
}
fun randomDay():String {
val week = listOf ("Monday", "Tuesday", "wednesday", "thursday", "friday", "saturday", "sunday")
return week[ Random().nextInt(7)]
}
I am getting error from return statement, I think from Random. Please help me to understand this and fix this code.

Just remove the parentheses: Random.nextInt(7).
Like this it uses the companion object (Default) of class Random which implements the abstract class Random with a default behaviour.
From the documentation:
The companion object Random.Default is the default instance of Random

It happened because you are trying to invoke function of abstract class, but abstract class have no instance. Instead you can use static function from Random companion object
Random.nextInt(yourIntValue)

Related

Kotlin: Specify input-constraints in interface

Lets say I have the following interface:
interface MathThing {
fun mathFunction(x : Int)
}
Let's say the constraint I want to put onto this function is that x cannot be negative.
How can I make sure that every time this (or any other arbitrary) condition isn't met on a object of type MathThing, a (custom) exception is thrown?
One way is to use a wrapper class for your function parameters. You can make an extension function so it's a little easier to pass values to the function.
data class NonNegative(val value: Int) {
init{ if (value < 0) throw IllegalArgumentException("Input must not be negative.") }
}
fun Int.nonNegative() = NonNegative(this)
interface MathThing {
fun mathFunction(x : NonNegative)
}

Mocking an extension function with Mockito

How can I test an extension function with Mockito? It doesn't seem to work nicely.
This is my extension function
fun <T> CrudRepository<T, String>.findOneById(id: String): T? {
val o = findById(id)
return if (o.isPresent) o.get() else null
}
And this is what I'm trying to test
#Test
fun getIslandById() {
//given
BDDMockito.given(islandRepository.findOneById("islandId1"))
.willReturn(IslandEntity(tileList, "1", "islandId1")) //findOneById is my extension function
//when
val island = islandService.getIslandById("islandId1")
//then
Assertions.assertThat(island?.id).isEqualTo("islandId1")
}
But the preceeding test throws the following error
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
IslandEntity cannot be returned by findById()
findById() should return Optional
Any ideas?
Instance extension functions can be mocked like this with a little help of mockito-kotlin:
data class Bar(thing: Int)
class Foo {
fun Bar.bla(anotherThing: Int): Int { ... }
}
val bar = Bar(thing = 1)
val foo = mock<Foo>()
with(foo) {
whenever(any<Bar>().bla(any()).doReturn(3)
}
verify(foo).apply {
bar.bla(anotherThing = 2)
}
As I said in a comment above, in the bytecode extension functions are nothing more than static functions which accept receiver as a first argument. Therefore you can't mock an extension function with a Mockito since it is not able to mock static functions.
What you can do, in case that findById(id) is implemented by Repository and not another extension function, is next:
Mock return value of findById(id) instead.
Take a look at the sample code below:
#Test
fun getIslandById() {
//given
BDDMockito.given(islandRepository.findById("islandId1"))
.willReturn(Optional.of(IslandEntity(tileList, "1", "islandId1"))) //mock findById function
//when
val island = islandService.getIslandById("islandId1")
//then
Assertions.assertThat(island?.id).isEqualTo("islandId1")
}
This way you are indirectly mocking your extension by providing it a mocked value that you want it to operate on.
Note: Error that you posted above says that your findById(id) should return an optional. So, wrap your return value of findById(id) function with an optional by calling Optional.of(result).

Implicit not found on store

I have followed the pattern from examples on GitHub. When I call store on the model object, passing an instance of the entity, I get a compile error indicating one of the implicit parameters is missing as shown below.
could not find implicit value for parameter sg: com.outworkers.phantom.macros.SingleGeneric.Aux[com.ss.wuhu.settlement.entity.Settlement,Repr,HL,Out]
I guess I am missing something obvious. Could someone please point out how to bring the implicit into scope?
Regards
Meeraj
This is the code snippet where I am storing the data.
import akka.Done
import com.outworkers.phantom.dsl._
import com.outworkers.phantom.connectors.{CassandraConnection, ContactPoints}
import com.ss.wuhu.settlement.entity.Settlement
import com.ss.wuhu.settlement.entity.mapping.{SettlementForCourierModel, SettlementForVendorModel}
object Connector {
private val hosts = Seq("127.0.0.1") // TODO from environment
lazy val connector: CassandraConnection = ContactPoints(hosts).keySpace("wuhu_order")
}
class SettlementDatabase(override val connector: CassandraConnection) extends Database[SettlementDatabase](connector) {
object SettlementForCourierModel extends SettlementForCourierModel with connector.Connector
object SettlementForVendorModel extends SettlementForVendorModel with connector.Connector
def truncateAll() = {
Database.truncate()
}
def store(set: Settlement) = {
for {
v <- Database.SettlementForVendorModel.store(set)
d <- Database.SettlementForCourierModel.store(set)
} yield (Done)
}
}
object Database extends SettlementDatabase(Connector.connector)
This is a known bug with an open issue: https://github.com/outworkers/phantom/issues/774
I suggest either using the workaround as described in the link above, or my workaround which was creating my own .store() using .insert().
example:
def myStore(person: Person) : Future[ResultSet] =
insert
.value(_.name, person.name)
.value(_.age, person.age)
.value(_.timeCreate, person.timeCreate)
.future()

Phantom's generated `store` method throws a ClassCastException at runtime

I have the following Phantom table definition:
package myPackage
import com.outworkers.phantom.CassandraTable
import com.outworkers.phantom.connectors.RootConnector
import com.outworkers.phantom.dsl._
import com.outworkers.phantom.keys.{PartitionKey, PrimaryKey}
import scala.concurrent.Future
case class KeysTwoThreeAndFour(myKeyTwo: Int, myKeyThree: String, myKeyFour: Int)
abstract class MyTable extends CassandraTable[MyTable, Int] with RootConnector {
object myKeyOne extends IntColumn(this) with PartitionKey
object myKeyTwo extends IntColumn(this) with PrimaryKey
object myKeyThree extends StringColumn(this) with PrimaryKey
object myKeyFour extends IntColumn(this) with PrimaryKey
object myValue extends IntColumn(this)
def insertValue(myKeyOne: Int, valuesMap: Map[KeysTwoThreeAndFour, Int]): Future[Unit] = {
val resultFutures = for ((key: KeysTwoThreeAndFour, myValue) <- valuesMap) yield {
store(myKeyOne, key.myKeyTwo, key.myKeyThree, key.myKeyFour, myValue).future()
}
Future.sequence(resultFutures).map { _ => () }
}
}
This compiles fine, but at runtime throws the following exception:
java.lang.ClassCastException: scala.Tuple5 cannot be cast to scala.runtime.Nothing$
at myPackage.MyTable$anon$macro$1$1.store(MyTable.scala:10)
at com.outworkers.phantom.CassandraTable.store(CassandraTable.scala:125) ~[com.outworkers.phantom-dsl_2.11-2.7.6.jar:2.7.6]
at myPackage.MyTable$$anonfun$2.apply(MyTable.scala:19)
at myPackage.MyTable$$anonfun$2.apply(MyTable.scala:18)
...
I am following the examples in the bottom of the Phantom table docs, what seems to be the problem? Is the issue perhaps that I have a simple Int as my "Record" type instead of an actual class?
I am using phantom-dsl 2.7.6, Play Framework 2.3.10 and Scala 2.11.11.
Note that the following code works fine:
insert
.value(_.myKeyOne, myKeyOne)
.value(_.myKeyTwo, key.myKeyTwo)
.value(_.myKeyThree, key.myKeyThree)
.value(_.myKeyFour, key.myKeyFour)
.value(_.myValue, myValue)
.future()
Thanks.
It seems that the issue was due to the "Record" type being a primitive, instead of a class; in other words, wrapping my Int in a case class having that Int as the only member solved the problem.
Additionally, there was a problem with the Select statement, which was solved too:
java.util.concurrent.ExecutionException: Boxed Error
at com.outworkers.phantom.CassandraTable.fromRow(CassandraTable.scala:85) ~[com.outworkers.phantom-dsl_2.11-2.7.6.jar:2.7.6]
at com.outworkers.phantom.SelectTable$$anonfun$select$1.apply(SelectTable.scala:24) ~[com.outworkers.phantom-dsl_2.11-2.7.6.jar:2.7.6]
at com.outworkers.phantom.SelectTable$$anonfun$select$1.apply(SelectTable.scala:24) ~[com.outworkers.phantom-dsl_2.11-2.7.6.jar:2.7.6]
at com.outworkers.phantom.builder.query.SelectQuery.fromRow(SelectQuery.scala:59) ~[com.outworkers.phantom-dsl_2.11-2.7.6.jar:2.7.6]
at com.outworkers.phantom.builder.query.RootExecutableQuery$class.singleResult(ExecutableQuery.scala:176) ~[com.outworkers.phantom-dsl_2.11-2.7.6.jar:2.7.6]
at com.outworkers.phantom.builder.query.SelectQuery.singleResult(SelectQuery.scala:33) ~[com.outworkers.phantom-dsl_2.11-2.7.6.jar:2.7.6]

Grails validate fields with default values

We have a class like this in a Grails 2.4.3 application (migrated from 2.3.8):
#Validateable
class Foo {
Integer noDefault;
Integer withDefault = 1;
static constraints = {
noDefault(nullable:false)
withDefault(nullable:false)
}
}
This class is being instantiated in a complex configuration mechanism using a Map like this:
[
noDefault: 0,
withDefault: 2
]
(In fact the Map is part of a huge one, but the class constructor sees this small one.) Formerly the class worked if we omitted the withDefault entry from the config map, using the default value which is not null. In Grails 2.4.3, however, it tells me that this field cannot be null. I can fix it by letting it be null in the constraint, but it lets setting the explicite value null (and overwrite the default value), which causes problem during operation.
Do you know some workaround, which preserves the semantics and correct operation?
Thanx in advance, best regards: Balázs
What you are describing is not consistent with what I would expect and not consistent with the behavior I am seeing. The project at https://github.com/jeffbrown/validatedefaults contains the following code.
At https://github.com/jeffbrown/validatedefaults/blob/master/src/groovy/demo/Foo.groovy
// src/groovy/demo/Foo.groovy
package demo
import grails.validation.Validateable
#Validateable
class Foo {
Integer noDefault;
Integer withDefault = 1;
static constraints = {
noDefault(nullable:false)
withDefault(nullable:false)
}
}
The test at https://github.com/jeffbrown/validatedefaults/blob/master/test/unit/demo/FooSpec.groovy passes:
// test/unit/demo/FooSpec.groovy
package demo
import spock.lang.Specification
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
#TestMixin(GrailsUnitTestMixin)
class FooSpec extends Specification {
void 'test validating default values'() {
given:
def map = [noDefault: 0]
def foo = new Foo(map)
expect:
foo.validate()
}
}
When I run the app I get the same behavior.
// grails-app/conf/BootStrap.groovy
import demo.Foo
class BootStrap {
def init = { servletContext ->
def map = [noDefault: 0]
def foo = new Foo(map)
// this prints true...
println "Foo is valid? : ${foo.validate()}"
}
def destroy = {
}
}
I hope that helps.

Resources