6

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

Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35
Shafique Jamal
  • 1,550
  • 3
  • 21
  • 45

2 Answers2

5

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.

Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35
0

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.

saver
  • 2,541
  • 1
  • 9
  • 14
  • 1
    You will have to override in this wrapper all methods in `Matchers`/`AnyFunSpec` that you want to use, as explained in my answer. I'd definitely not go this way. What is `@Test` by the way? Will `sbt test` run such a test? – Tomer Shetah Jan 04 '21 at 05:39
  • No, my main idea was to wrapper code ```it should "test1" in { println("test1") }``` into java method with parameters, and call from child class. I didn't expect ```sbt``` tool will be single possibility for building project. I worked with ```maven``` or ```gradle```, and they can compile ```scala``` classes thanks for plugins. ```@Test``` is an annotation for defining methods that will be triggered by the testing plugin. – saver Jan 05 '21 at 23:41