Mocking BiFunction with Spock Java/Groovy - testing

Pretty new to Spock. Trying to mock a function that returns a BiFunction unsuccessfully.
The function looks like
public interface myInterface {
Optional<BiFunction<Object, Object, Object>> myAwesomeFunc()
}
Trying to mock like
def mockBiFunction = Mock(BiFunction)
mockMyInterface.myAwesomeFunc >> mockBiFunction
mockBiFunction.apply(*_) >> mockReturnVal
This results in
No signature of method: com.sun.proxy.$Proxy49.apply() is applicable for argument types: (org.spockframework.lang.SpreadWildcard) values: [*_]
Possible solutions: apply(java.lang.Object, java.lang.Object), any(), any(groovy.lang.Closure), every(), tap(groovy.lang.Closure), every(groovy.lang.Closure)
groovy.lang.MissingMethodException: No signature of method: com.sun.proxy.$Proxy49.apply() is applicable for argument types: (org.spockframework.lang.SpreadWildcard) values: [*_]
Possible solutions: apply(java.lang.Object, java.lang.Object), any(), any(groovy.lang.Closure), every(), tap(groovy.lang.Closure), every(groovy.lang.Closure)
Tried with
mockBiFunction(*_) >> mockReturnVal
That doesn't work either.
Edit:
Tried with
mockBiFunction.apply(object1, object2) >> mockReturnVal
This fails with
Cannot invoke method rightShift() on null object
java.lang.NullPointerException: Cannot invoke method rightShift() on null object
When I have mocked it then why is it null ??

Actually, your interface method returns an Optional, not a BiFunction. More precisely, it returns Optional<BiFunction<Object, Object, Object>>. Therefore, your interface mock needs to return an Optional as well when stubbing myAwesomeFunc(). That is what IMO is wrong with your code.
Your own answer does not look logical to me, but that might be because both in your question and your answer you only provided incoherent sets of snippets instead of a proper MCVE. Please do learn how to ask good questions. You seem to be an experienced developer, wrestling with optionals of bi-functions etc. Therefore, you ought to know how to make your problem reproducible. If you are unable to do that, you cannot expect good answers or people even feeling inclined to try.
Anyway, here is my take:
package de.scrum_master.stackoverflow.q71602791
import spock.lang.Specification
import java.util.function.BiFunction
class BiFunctionMockTest extends Specification {
def "mock BiFunction"() {
given:
def biFunction = Mock(BiFunction) {
apply(*_) >> "dummy"
}
def myInterface = Mock(MyInterface) {
myAwesomeFunc() >> Optional.of(biFunction)
}
def underTest = new MyInterfaceUser(myInterface: myInterface)
expect:
underTest.doSomething().get().apply("foo", "bar") == "dummy"
}
interface MyInterface {
Optional<BiFunction<Object, Object, Object>> myAwesomeFunc()
}
static class MyInterfaceUser {
MyInterface myInterface
def doSomething() {
myInterface.myAwesomeFunc()
}
}
}

Ah looks like all I had to do was to use a function as the mock return value from the BiFunction so something like following works
def mockMyAwesomeFunc = abc -> mockReturnVal
mockBiFunction.apply(object1, object2) >> mockMyAwesomeFunc
instead of doing
mockBiFunction.apply(object1, object2) >> mockReturnVal
Feeling really stupid now !!
Edit -- Updating the answer to more closely reflect the actual working code - this is what worked
def mockBiFunction = Mock(BiFunction)
mockMyInterface.myAwesomeFunc >> Optional.of(mergeBiFunction)
mergeBiFunction.apply(_, _) >> (a, b) -> {
return mockValue
}

Related

Is there a way to make the first digit of int always start with 1 in Kotlin

Let's say I have the following class constructor:
class Car(val brand: Brand,val modelName: String, val version: Int){}
If for example, I want the version number to always start with 1. Is there a way to manipulate it in the class body to achieve this ?
Meaning:
val firstdigit:Int = abs(version).ToString().Substring(0,1)
And then parse it to Int. But how to replace the original first digit after that?
I'm just learning Kotlin and I got a bit stuck with this
Is this what you had in mind?
class Car(val brand: Brand, val modelName: String) {
val version = getNextVersion()
companion object {
private var nextVersion = 0
private fun getNextVersion(): Int {
nextVersion++
if (nextVersion.toString()[0] != '1') {
nextVersion = (10.0.pow(ceil(log10(nextVersion.toDouble())))).toInt()
}
return nextVersion
}
}
}
You already said in the comments that you want the number to increment per instance, so the caller shouldn't be providing that number in the first place really! But just generally, here's two approaches to sanitising your input parameters:
1) Make it the caller's responsibility to provide valid data
init {
require(version.toString().first() == '1') { "Needs to start with 1 thanks" }
}
require throws an IllegalArgumentException if it fails, which is the standard exception for "the value of this argument is invalid". Should the class be responsible for taking bad data and trying to "fix" it, or should the caller be handling that - and maybe not constructing an instance at all if it doesn't have valid data?
2. create a newInstance function that uses valid data, and keep the constructor private
class Thing private constructor(val number: Int){
companion object {
fun newInstance(num: Int): Thing {
return Thing(abs(num))
}
}
}
fun main() {
Thing.newInstance(-2).let { println(it.number)}
}
If it makes sense for the class itself to sanitise the input parameters, you can delegate construction to a function that takes care of that, and prevent things from calling the constructor directly with potentially bad data.
This can cause issues with e.g. serialisation libraries (which want to call the constructor directly) but in that case you could leave the constructor public, and just advise callers to call newInstance instead. Not ideal, but it's an option!

How to chain functions returning Validated, Option, Either? (Monad Transformer)

I have simple three functions returning arrow-kt data types
fun validate(input): Validated<Error, Input> = ...
fun fetch(input): Option<Error, InputEntity> = ...
fun performAction(inputEntity): Either<Error, Output> = ...
And want to chain something like this (can use any available function instead of map)
validate(input)
.map{fetch(it)}
.map{performAction(it)}
Only solution I could come up with is to replace Validated and Option with Either and chain using flatMap. Is there any better functional way to make it work without updating the existing functions?
👋 What #pablisco described is correct, but you can keep it simpler by using some syntax extensions we provide to convert from one type to the other. Note that both options are correct, but Monad Transformers can be a bit convoluted and too powerful, and they're also prone to get removed from Arrow soon, once we finally figure out our delimited continuations style completely. But that is out of scope here. Here is how you could solve it by using the extensions I mentioned:
import arrow.core.*
import arrow.core.extensions.fx
sealed class Error {
object Error1 : Error()
object Error2 : Error()
}
data class InputEntity(val input: String)
data class Output(val input: InputEntity)
fun validate(input: String): Validated<Error, InputEntity> = InputEntity(input).valid()
fun fetch(input: String): Option<InputEntity> = InputEntity(input).some()
fun performAction(inputModel: InputEntity): Either<Error, Output> = Output(inputModel).right()
fun main() {
val input = "Some input"
Either.fx<Error, Output> {
val validatedInput = !validate(input).toEither()
val fetched = !fetch(validatedInput.input).toEither { Error.Error1 /* map errors here */ }
!performAction(fetched)
}
}
Hope it was useful 👍
What you are looking for is called a Monad Transformer. In Arrow, you may have seen them already, they end with a T at the end. Like OptionT or EitherT.
There are some good examples here for EitherT:
https://arrow-kt.io/docs/0.10/arrow/mtl/eithert/
And here for OptionT:
https://arrow-kt.io/docs/0.10/arrow/mtl/optiont/
The idea would be that to choose what your final value is going to be (let's say Either) and using an FX block you can then use EitherT to convert the other types to an Either.

How can I assign a value to KMutableProperty parameter?

In a method I would like to receive KMutableProperty as parameter and assign a value to it.
Another question is what is the correct way of passing a parameter into such a method.
Basically I would like to have something like that:
class MyBinder {
...
fun bind(property: KMutableProperty<Int>): Unit {
property.set(internalIntValue)
}
}
And then call it in another class
myBinder.bind(this::intProperty)
Kotlin 1.0 does not allow the this::intProperty syntax, but this is being worked currently and will be available soon as a part of the early access preview of 1.1 (issue, KEEP proposal).
With this in mind, I'd consider doing what you're describing in another way, for example making bind accept a lambda which sets the property:
class MyBinder {
fun bind(setProperty: (Int) -> Unit) {
setProperty(internalIntValue)
}
}
...
myBinder.bind { intProperty = it }
Anyway, to answer your question about setting the value of KMutableProperty: to set the value of some property or, technically speaking, to invoke the property setter, you should know its arity, or the number of parameters that property (and its getter/setter) accepts. Properties declared in a file do not accept any parameters, member properties and extension properties require one parameter (the receiver instance), while member properties which are also extensions take two parameters. These kinds of properties are represented by the following subtypes of KMutableProperty respectively: KMutableProperty0, KMutableProperty1, KMutableProperty2 -- the number means the arity and their generic type parameters mean the types of receivers. Each of these property types has a set method with the corresponding parameters. Some examples:
fun setValue(property: KMutableProperty0<Int>, value: Int) {
property.set(value)
}
fun setValue(property: KMutableProperty1<SomeType, Int>, instance: SomeType, value: Int) {
property.set(instance, value)
}
Note that there's no set (or get) method in the abstract KMutableProperty interface precisely because it's impossible to declare it, not knowing the number of required receiver parameters.
Additionally to Alexander's answer, you can try something like this:
import kotlin.reflect.KMutableProperty
class Binder {
val internalIntValue = 10
fun bind(self: Any, aProperty: KMutableProperty<Int>) {
aProperty.setter.call(self, internalIntValue)
}
}
class Foo {
var bar = 1
fun changeBar() {
Binder().bind(this, Foo::bar)
}
}
fun main(args: Array<String>) {
val foo = Foo()
assert(1 == foo.bar)
foo.changeBar()
assert(10 == foo.bar)
}
A more robust/safe way to do the same thing:
fun <T> bind(self: T, aProperty: KMutableProperty1<T, Int>) {
aProperty.set(self, internalIntValue)
}
My thanks to Alexander. His answer gave me the previous idea.

How do I cast a JavaScript object to a Kotlin object?

I have received a JavaScript object in response to a remote HTTP request. I have a kotlin model (trait) that defines the various fields I expect on the object (the nullable ones are optional).
First, I want to do an is check to make sure my object is in fact of the expected type. I initially tried payload is MyModel but that doesn't work due to the way the is operator is written in kotlin.js.
Second, I want to cast to MyModel so I can get auto-complete, etc. on the object while I work with it. Normally, the is alone would be enough but since that doesn't work I need something for this problem as well.
I would like to avoid manually populating my object from a dynamic. I wouldn't mind doing this so much if I could use by Delegates.mapVal(...) but that requires a Map<String, Any?> and I don't know how to get my dynamic/Any? payload into a Map<String, Any?>.
1) We don't have structure check for is in performance reasons.
I don't sure that we need generic solution for this, but anyway I created issue about it, feel free to vote or star it to get updates.
2) is enough if you use smart cast, like:
if (payload is MyModel) {
// call MyModel members on payload
}
But don't forget about (1) :)
3) You can write something like:
class MapDynamic<out V>(val d: dynamic) {
public fun get(thisRef: Any, desc: PropertyMetadata): V {
return d[desc.name]
}
}
class Foo(data: dynamic) {
val field: Int by MapDynamic(data)
}
fun main(args : Array<String>) {
val f = Foo(object { val field = 123 })
println(f.field)
}
But it looks too verbose, but You can add additional logic for e.g. when data don't have requested field. And if You don't need custom logic I think cast is enough.
For the second part, the cast, you can do:
fun responseHandler(payload: dynamic) {
val myModel = payload as MyModel
}
or
fun responseHandler(payload: dynamic) {
val myModel: MyModel = payload
}
This will throw an NPE if payload is null, but it won't actually validate that the payload matches MyModel. In particular, you may end up with null fields/properties that shouldn't be if the payload was missing those fields/properties.

Approaches to testing that a method is not available on a type

Given a type hierarchy for a game which strongly distinguishes whose turn is next:
trait Game
trait BlackToPlay extends Game {
def move(p: BlackPiece, s: Square): Either[FinishedGame, WhiteToPlay]
}
trait WhiteToPlay extends Game {
def move(p: WhitePiece, s: Square): Either[FinishedGame, BlackToPlay]
}
Can I make the following, important assertion without resorting to reflection?
"A game with white to play" should {
"not allow black to play" in {
// an instance of whiteToPlay should not
// have the `move(BlackPiece, Square)` method.
}
}
EDIT: My attempt to implement #Martin's solution doesn't work. Any thoughts on what's wrong here? From the REPL:
scala> class B() {
| def b(s: String) = s
| }
defined class B
scala> val b = new B()
b: B = B#420e44
scala> b.c("")
<console>:8: error: value c is not a member of B
b.c("")
^
scala> b match {
| case _: { def c(s: String) } => false
| case _ => true
| }
warning: there were unchecked warnings; re-run with -unchecked for details
res7: Boolean = false
res7 should have been true, because b should not match on the structural type of { def c(s: String) }
You don't test what the type system already guarantees. In fact, the type system is already a test of certain properties of your program.
You could further on to test that the types you have guarantee a certain property (like no player making a move twice in a row), but this kind of thing is restricted to languages like Agda and Coq, for now.
Assuming BlackPiece is not a subtype of WhitePiece:
WhiteToPlayInstance.move(BlackPiece, s) should not compile - which means you can't write a test for it. The type system ensures that you can't move a BlackPiece on a WhiteToPlay.
EDIT: As Thomas pointed out, the below answer is nonsense since structural types cannot be used in pattern matches in the JVM version of scala.
Under normal cicumstances this doesnt make much sense because scala is statically typed and things like that are taken care of by the compiler but if you do make massive use of reflection or structural typing in your code it might be a good test:
instance match {
case x: { def move(p: BlackPiece, s: Square): Either[FinishedGame, WhiteToPlay] } => // error
case _ => // no error
}
If you really want to test for such things, move the check from type checking to something dynamic. Assume that WhitePiece and BlackPiece share a common supertype Piece:
trait Game {
def move(p : Piece, s : Square) : Either[FinishedGame, WhiteToPlay]
}
trait BlackToPlay extends Game
trait WhiteToPlay extends Game
Then a test could look like this:
val b2p : BlackToPlay = ...
val bp : BlackPiece = ...
val wp : WhitePiece = ...
{a move bp} must not produce [IllegalMoveException]
{a move wp} must produce [IllegalMoveException]
I am not sure this would be good design, but it makes your system explicitly testable.
I know you didn't want a reflection solution, but you could (if scala 2.9 is acceptable) use the new Dynamic trait like this:
class ReflectionDynamic[T <: AnyRef](t: T) extends Dynamic {
def typed[A]: A = sys.error("doh");
def applyDynamic(name: String)(args: Any*) = {
val argRefs = args.map {
case a: AnyRef => a
case _ => sys.error("only AnyRefs")
}
t.getClass.getMethod(name, argRefs.map(_.getClass): _*).invoke(t, argRefs: _*)
}
}
... and that will give this positive test:
val dynamicWhiteToPlay = new ReflectionDynamic(whiteToPlay)
dynamicWhiteToPlay.move(new WhitePiece, new Square) must_== Right(blackToPlay)
... and this for negative:
dynamicWhiteToPlay.move(new BlackPiece, new Square) must throwA[NoSuchMethodException]
The question is akin to asking: Given val f: (Boolean) => Int, how can I test that f("hello world") is rejected by the compiler?
After some brief conversation at the Melbourne Scala User Group my question was validated (yay). After all, the restriction I'm trying to test for is included by design and therefore deserves a test.
Bernie Pope suggested that the mechanism required is Automated Theorem Proving. #daniel-c-sobral was kind enough to mention Agda and Coq in a slightly different context and indeed these are ATP technologies which could prove my application to be correct.
Another suggestion was to execute the offending code as a script and assert that it fails. A poor-mans eval, if you like.