How can one use ScalaTest in a Java test file?

Viewed 409

It is possible to use ScalaTest in a Java test file, and if so where can I find examples?

When I try something like:

// MyUTest.java

import org.scalatest.flatspec.AnyFlatSpec;
import org.scalatest.matchers.should.Matchers;

public class MyUTest extends AnyFlatSpec, Matchers {
  ...
}

I get an error that equal(Object) in Matchers clashes with the same method in matchers.dsl.MatherWords

2 Answers

TL;DR: You cannot do what you are trying.

As stated in Using Scala traits with implemented methods in Java:

From Java perspective Trait.scala is compiled into Trait interface. Hence implementing Trait in Java is interpreted as implementing an interface - which makes your error messages obvious. Short answer: you can't take advantage of trait implementations in Java, because this would enable multiple inheritance in Java (!)

and Matchers is a trait. However, to overcome this issue, you can just remove the Matchers extension, and have the test class:

import org.scalatest.flatspec.AnyFlatSpec;

public class MyUTest extends AnyFlatSpec {
    
}

Which will compile. Having said that, it will be really hard to actually use the the ScalaTest functionality in Java. For example, a simple test class will be:

public class MyUTest extends AnyFlatSpec {
    it should "test1" in { println("test1") }
}

The word should above, is declared at AnyFlatSpecLike, which is trait as well. So you cannot really use it. So I am not really sure how you can overcome this issue, as this is the very basic example that you can find in ScalaTest quick start.

After the above analysis, I think it's going to be really difficult to use ScalaTest in Java. What you can easily do, is the other way around. If you already support Scala, and you have ScalaTest, you can just test the java code in Scala. It is a bit less "organized" as you'd expect to see the java test classes under the java folder, which we just proved impossible. I think having this "mess" is the best solution in such structure.

I totally agree with @Tomer Shetah. I would like to add that you can create wrapper for java on scala:

class JavaScalaTestWrapper extends AnyFunSpec with Matchers {
  def println(x : scala.Any) = Predef.println(x)
  def shouldEqual(x : scala.Int, ) = SomeCode.someFunc(x) shouldBe s"${x}"
}

And after that you can extend all java test classes through this wrapper:

public class SomeOperationTestJava extends JavaScalaTestWrapper {
    @Test
    void someOperation() {
        SomeOperation so = new SomeOperation();
        println("=== test ===");
        assert(("test").equals(so.someOperation()));
        shouldEqual(3);
    }
}

And all scala styled code you can put in wrapper, and after that use these methods from original java code, like additional workaround.

Related