1

I'm trying to build myself a tiny mocking library to deal with quite obvious cases:

  1. Mock functions and record calls to them.
  2. Mock trait implementations and be able to record calls on the methods implemented.

The first I achieved with the following implementation:

class LoggedFunction1[A1, B](body: A1 => B) extends Function1[A1, B] {
    val calls = mutable.Buffer[A1]()

    override def apply(v1: A1): B = {
        calls += v1
        body(v1)
    }
}

object LoggedFunction {
    def apply[A1, B](body: A1 => B) = new LoggedFunction1(body)
}

So far, so good.

I was now wondering if I could use this FunctionN extension somehow to implement the methods of a trait, such as:

trait A {
    def m(i: Int)
}

class B extends A {
    override def m(i: Int) = LoggedFunction((a: Int) => a)
}

Now that of course doesn't compile, because m's return value must be of type Int and not Function1[Int, Int].

I could declare a companion value to contain my information, such as:

class C extends A {
    val _m = LoggedFunction((a: Int) => a)
    override def m(i: Int) = _m(i)
}

But meh. What I really would like to do is:

class D extends A {
    override val m = LoggedFunction((a: Int) => a)
}

In my mind the latest "should" somehow work, as I'm overriding a Function1[Int, Int] with a Function1[Int, Int], but it complains about me not overriding anything with m.

Is there any possibility I can override m using my LoggedFunction so I end up writing:

val test = new E
test.m(1)
test.m.calls should have size 1

If not: Why is it not possibly to override the method with a value containing a function?

markusthoemmes
  • 3,080
  • 14
  • 23

1 Answers1

2

In my mind the latest "should" somehow work, as I'm overriding a Function1[Int, Int] with a Function1[Int, Int]

Overriding a method with a function this way won't work, the two are really different things. See Functions vs methods in Scala.

In your precise use case, you could try the following:

override def m(i: Int) = LoggedFunction((a: Int) => a).apply(i)
Community
  • 1
  • 1
OlivierBlanvillain
  • 7,701
  • 4
  • 32
  • 51