1

version:

jdk1.8.0 Scala: 2.11

<properties>
 <junit.jupiter.version>5.2.0</junit.jupiter.version>
  <junit.platform.version>1.2.0</junit.platform.version>
</properties>
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-all</artifactId>
  <version>1.9.5</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-api</artifactId>
  <version>${junit.jupiter.version}</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-engine</artifactId>
  <version>${junit.jupiter.version}</version>
  <scope>test</scope>
</dependency>

I am following this question, which shows how to assert exception using junit 5 in java.

When I am trying to do the same in scala:

val closureContainingCodeToTest = () -> myClass.myMethod(data)   // or     val closureContainingCodeToTest = () => myClass.myMethod(data)
assertThrows(classOf[MyException], closureContainingCodeToTest)

I get this error:

 Error:(89, 48) type mismatch;
 found   : () => Unit
 required: org.junit.jupiter.api.function.Executable
    assertThrows(classOf[MyException], closureContainingCodeToTest)

This might be very simple question, but I could not found how to create Scala closure to Java Executable object in Scala.

Edit:

Adding a simple complete test:

package com.my.lib

import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.function.Executable

class myTest {

  @Test
  def myTest = {
    val closureContainingCodeToTest:Executable = () => throw new RuntimeException()
    assertThrows(classOf[RuntimeException], closureContainingCodeToTest)
  }
}

I get following error:

Error:(11, 53) type mismatch;
 found   : () => Nothing
 required: org.junit.jupiter.api.function.Executable
    val closureContainingCodeToTest:Executable = () => throw new RuntimeException()
Saurabh
  • 71,488
  • 40
  • 181
  • 244
  • Your code compiles and runs for me - after I added `Unit` return type to `myTest` that is. If you are using IDE then I think this is just a need to clean/rebuild the project to take into account you added `Executable`. I can recreate your error if I remove `Executable` from `closureContainingCodeToTest` but it compiles after adding back in and cleaning/rebuilding. – jacks Aug 23 '18 at 02:29
  • @Nio This is strange, Even with `mvn clean compile test` from terminal, I get same error. – Saurabh Aug 23 '18 at 05:00

3 Answers3

2

If we want to do it in Junit 5 style - you can do like in code below:

import org.junit.jupiter.api.{DisplayName, Test}
import org.junit.runner.RunWith
import org.scalatest.junit.{JUnitRunner, JUnitSuite}

@RunWith(classOf[JUnitRunner])
class Junit_5_Test extends JUnitSuite{

  object ExceptionTest {
    @throws(classOf[RuntimeException])
    def throwRunEx = throw new RuntimeException
  }

  @Test
  @DisplayName("Example with JUnitSuite")
  def throwsExceptionWhenCalled_With_JUnitSuite() {
    import ExceptionTest._
    assertThrows[RuntimeException]{ throwRunEx}
  }

}

To do like this - u need to include this in your build.sbt:

"org.junit.jupiter" % "junit-jupiter-api" % "5.2.0" % Test,
 "org.scalatest" %% "scalatest" % "3.2.0-SNAP10" % Test
Dmitry Kaltovich
  • 2,046
  • 19
  • 21
1

You can coerce the function type () => myClass.myMethod(data) into an Executable by being explicit about the return type of the closure ie. add Executable

import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.function.Executable

class MyClassTests {

  val closureContainingCodeToTest: Executable = () => (new MyClass).myMethod(data)

  @Test
  def throwsExceptionWhenCalled(): Unit = {
    assertThrows(classOf[MyException], closureContainingCodeToTest)
  }

}

Alternatively, if you inline it then you don't even need to be explicit.

import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test

class MyClassTests {

  @Test
  def throwsExceptionWhenCalled(): Unit = {
    assertThrows(classOf[MyException], () => (new MyClass).myMethod(data))
  }

}

Also note that your test methods need to return Unit else they will never be run.

jacks
  • 4,614
  • 24
  • 34
  • Thanks, however these I had tried and gives same error. Also I have `_execute` method, dont get confused this with `execute` method of `Executable` interface. – Saurabh Aug 22 '18 at 17:13
  • No worries. Thats weird, its compiling/running ok for me. Maybe post your full code? Are you using junit.jupiter 5.2.0? – jacks Aug 22 '18 at 17:23
  • Yes, junit.jupiter 5.2.0 I have updated the question with a simple example. – Saurabh Aug 23 '18 at 03:40
1

To build off of the previous answers, I wanted to write multiple lines of test code and not call only MyClass.myMethod(data)

import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.function.Executable

class MyClassTest {

  @Test
  def throwsExceptionWhenCalled(): Unit = {
    assertThrows(classOf[MyException], new Executable {
      override def execute(): Unit = {
        val data = generateBadData()
        new MyClass().myMethod(data) // throws MyException
      }
    })
  }

}
Taylor
  • 510
  • 6
  • 14