Home > Back-end >  Unit testing function embedded within another function in Scala
Unit testing function embedded within another function in Scala

Time:11-29

I was wondering if there is a way to test a function embedded within another function in Scala? Or the only to test it is to lift it as a top level function??

  def processNumbers(n: Int): Int = {
    def isEven(num: Int): Boolean = num % 2 == 0
    if (isEven(n)) 0 else -1
  }

For example, in the code snippet above I would like to be able to unit test isEven without having to make it the top level function.

By "top-level", I meant writing it at the same level as the "parent" function. In this case it would look like:

  def isEven(num: Int): Boolean   = num % 2 == 0
  def processNumbers(n: Int): Int = if (isEven(n)) 0 else -1

CodePudding user response:

Nested methods are not accessible outside of their parent method/function so they cannot be tested in separation. In this regard they are the the same group as private methods - you use them because it is convenient to extract some functionality to separate method and give it a name, but it is not useful on its own and it would not give you much value testing it outside of its context.

If something would make sens to be used outside of the parent method, it would make sense to make it a public method and test it.

CodePudding user response:

Inner methods are compiled as instance methods. When you compile your code using scalac and then decompile it again you'll see that the inner methods gets compiled as an instance methods.

public class StackoverflowQuestionClass {
  public int processNumbers(int n) {
    return this.isEven$1(n) ? 0 : -1;
  }

  private final boolean isEven$1(int num) {
    return num % 2 == 0;
  }
}

So its most likely possible to access this method using a reflection utility and actually make assertions. But I would strongly encourage you not to do so.

If you need to make assumptions about the way the code is compiled, while you're writing tests, you most likely are doing something wrong.

You should treat a method as a single unit of testing. If you really want to test the inner method you'll have to give up a bit of encapsulation and move the inner method outwards.

  • Related