Cannot Resolve Symbol "Scalatest" - scala

I am trying to use scalatest, but Intellij cannot recognize:
import org.scalatest._
Here is my build.sbt file, located in the same directory as my scalatest.jar file.
scalaVersion := "2.11.2"
libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.4" % "test"
Thanks

So you have by convention two source folders:
src/main/scala/...
src/test/scala/...
The first is shown blue, the second green in IntelliJ IDEA. The library dependencies in sbt are associated with either of these, so
"org.foo" % "bar_2.11" % "1.2.3"
Is a main dependency, available to main sources (and also test, because test depends on main). And
"org.foo" % "bar_2.11" % "1.2.3" % "test"
Is a test dependency, only available to test sources. The idea is that these are libraries which are not required for your product, but only to run the unit tests.
In your example, Scala-Test is only available to test sources, so trying to import it from main sources will fail.

Related

Unable to resolve dependencies from test

I am new to scala. I am trying to create a scala project in IntellIj and adding a test class.
I am using the below 2 dependencies in sbt.
libraryDependencies += ("org.scalactic" %% "scalactic" % "3.0.8")
// https://mvnrepository.com/artifact/org.scalatest/scalatest
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % Test
But I am unable to use the class FunSuite in the test class 'ProcessCSVTest.scala' for testing as it is giving a compilation error.
Although I can see the dependencies in the external library in my IntellIj
Build.sbt file
name := "CSVParser"
version := "0.1"
scalaVersion := "2.13.0"
libraryDependencies += ("org.scalactic" %% "scalactic" % "3.0.8")
// https://mvnrepository.com/artifact/org.scalatest/scalatest
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % Test
The entire code can be found here - https://github.com/practice09/CSVParser
Can anyone please tell me where I am doing wrong?
One issue is the test ProcessCSVTest.scala is under main sources which means ScalaTest needs to be on the main classpath, however in build.sbt ScalaTest dependency is scoped to the Test classpath
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % Test
So if you remove Test scope like so
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8"
then ScalaTest will end up on the main classpath and we can add the following import
import org.scalatest.FunSuite
However my suggestion is to move the tests out of the main sources and put them under src/test/scala/, and then scope the dependency under Test like before
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % Test
The following command builds an example with correct project structure expected by sbt
sbt new scala/scala-seed.g8
so try exploring how it is setup and fit your project to match.
Because FunSuite is in a package, you need to add
import org.scalatest.FunSuite
If you put the cursor on it and press Alt+Enter, you should get a suggestion to fix it.

object mockito is not a member of package org

Relatively new to sbt and Mockito.
I want to use Mockito in tests, but I'm getting errors related to the Mockito imports when I compile the tests
Imports in test file:
import org.scalatest._
import org.mockito.Mockito._
import org.scalatest.mockito.MockitoSugar
sbt file:
name := "blah"
version := "0.1"
scalaVersion := "2.13.0"
libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.8"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % "test"
libraryDependencies += "org.mockito" % "mockito-core" % "1.8.5" % "test"
I get these error messages when the tests (fail to) compile:
object mockito is not a member of package org [error] import org.mockito.Mockito._
and also:
Symbol 'type org.mockito.MockSettings' is missing from the classpath.
[error] This symbol is required by 'value org.scalatest.mockito.MockitoSugar.mockSettings'.
I've had a play around with changing some of the versions of scalatest and mockito in the sbt file, but not really if that's getting at the root of the problem or not.
Thanks for any help!
You're using a very old version of Mockito, which is older than the one Scalates relies on, you probably need some 2.x.x version.
On the other hand, I'd recomend you to go fo mockito-scala rather than mockito-core and skip the Scalatest provided classes altogether as they are quite basic.
I suspect you have a caching problem. This happens especially with Intellij.
Here 2 ideas:
Reload the sbt project. See https://stackoverflow.com/a/20466144/2750966
Close the project / delete .idea an open the project newly with Intellij.
Let me know if it is not related with Intellij

Scala library available in both compile and test configuration

I have a library that I wish to expose in both the unit tests in Scala and the code itself.
In sbt, I added my library dependency with configuration "test" and then it's available for tests but I cannot use it in the code. If I leave the configuration be or add "compile" it's not available to be imported in unit tests.
libraryDependencies ++= Seq(
"org.scalacheck" %% "scalacheck" % "1.14.0",
"org.scalatest" %% "scalatest" % "3.0.6" % "test",
"org.scalactic" %% "scalactic" % "3.0.6" % "test")
The main problem is that I expose an abstract class I want to use all over the place in other code: abstract class UnitSpec extends FlatSpec with Matchers with ScalaCHeckDrivenPropertyChecks and also use in the tests of the library. If I add "test" to ScalaCheck it cannot find it in the main code of the library. If I leave it as is, it cannot from org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks. This used to be OK and work fine with 3.0.5 and GeneratorDrivenProperyChecks but that's been deprecated.
Is there a way to achieve what I want? I tried "test->compile" but that also doesn't do what I had hoped...
You can combine configurations. In order to have a library both in compile and test you just add bot configurations.
// wrong: libraryDependencies += "<organization>" %% "<module>" % "<version>" % "compile->compile" % "test->compile"
The syntax means roughly: project configuration dependsOn(->) configuration of libraryDependency.
Update
You can also add the dependency twice with different configurations.
libraryDependencies += "<organization>" %% "<module>" % "<version>",
libraryDependencies += "<organization>" %% "<module>" % "<version>" % "test"
Update 2
I think the syntax in the first example is not what I meant to provide.
libraryDependencies += "<organization>" %% "<module>" % "<version>" % "compile->compile;test->compile"
At least that is what I use in my libraryDependencies.
So you need a trait from the Scalatest JAR in non-test code. I am not sure why it worked before, but it would make sense to me just to remove % "test" from the scalatest dependency. That will make it available in compile and everything from compile is available in test too.
And for Scalactic I think the main use-case for it as a separate dependency is when you need it in compile but only use Scalatest in test (or don't use it at all). If they are both needed for tests only (or for compile), Scalatest will bring Scalactic with it.
I tried "test->compile" but that also doesn't do what I had hoped...
"test->compile" is the same as "test":
A configuration without a mapping (no "->") is mapped to "default" or "compile". The -> is only needed when mapping to a different configuration than those.

sbt Test scope includes Runtime?

I'm configuring SLF4J within an SBT application and the Test vs Runtime scopes are working differently than I'd expect.
The setup I want:
tests (sbt test): use slf4-simple as the implementation
bundle/production runtime (sbt run): use log4j-slf4j-impl
Relevant build.sbt (sbt 0.13) section:
libraryDependencies += "org.slf4j" % "slf4j-simple" % "1.7.25" % Test,
libraryDependencies += "org.apache.logging.log4j" % "log4j-api" % 2.8.2 % Runtime,
libraryDependencies += "org.apache.logging.log4j" % "log4j-core" % 2.8.2 % Runtime,
libraryDependencies += "org.apache.logging.log4j" % "log4j-slf4j-impl" % 2.8.2 % Runtime
The error I'm getting is that there are two slf4j bindings present, the log4j one and the simple.
I'm wondering how the Runtime dependencies can be excluded from the Test scope, or if this is the wrong approach here.
To distill the question: I want to use a few different jars at runtime vs test that are mutually exclusive. How can this be done in sbt 0.13?
The issue is that Test scope includes Compile and presumably Runtime. So anything you add in Runtime it's also added in Test.
You can try to exclude log4j-slf4j-impl from the Test classpath like this:
fullClasspath.in(Test) := fullClasspath.in(Test).value.filterNot(_.data.getName.contains("log4j-slf4j-impl"))

How to toggle between project and library dependencies in SBT?

It's easy to declare managed library dependencies in SBT, eg
libraryDependencies ++= Seq(
"org.specs2" %% "specs2" % "1.12.2" % "test" ,
"junit" % "junit" % "4.7" % "test"
)
And while it's not as easy to declare project dependencies in SBT, I can do that too:
object RichMath extends Build {
lazy val myApp = Project("RichMath", file(".")) dependsOn(richUtil)
lazy val richUtil = RootProject(file("../RichUtil"))
}
But in practice, I typically want to change between project mode, where changes are immediately visible in upstream projects, and library mode, where I must publish changes to see them in dependent projects, as code matures.
Early in code-base's life, or whenever I'm wanting to make frequent changes across modules, I don't want the hassle of re-publishing just to see changes upstream. But in stable/mature code, I want to specify exactly what version's I'm depending upon.
It seems like SBT treats the two dependencies as completely different. Is there a more straight-forward way to switch between project- and library- dependencies than rewriting my build definition?
I have a few scenarios for my sbt scripts (tests, publishing, production). I start sbt from script (from bash, you may have other environment) with DO=TESTS sbt for example. This is my dynamic dependencies with regard of environment variable:
if (sys.env.contains("LOCAL_BUILD")) {
Seq[Project.Setting[_]](
unmanagedResourceDirectories in Compile <+= baseDirectory { _ / "src" / "main" / "scala" },
libraryDependencies ++= {
Seq(
"org.digimead" %% "digi-lib-slf4j" % "0.2.1-SNAPSHOT" % "test",
"org.digimead" %% "digi-lib-test" % "0.2.1-SNAPSHOT" % "test",
"org.scalatest" %% "scalatest" % "1.9" % "test"
)
}
)
} else {
Seq[Project.Setting[_]](
libraryDependencies ++= {
Seq(
"org.slf4j" % "slf4j-log4j12" % "1.7.1"
)
}
)
}
As you can see I may have different project settings with single .sbt definition controlled by one environment variable. The environment variable affect all project/subproject bunch.
It is true that the two types of dependencies are treated rather differently and it would be nice if they were not. The main obstacle is that sbt needs to know about all external projects before settings are loaded (for various reasons).
For now, the easiest solution is probably an environment variable or system property as described in another answer. Going forward, the following is very close to being possible in sbt, but still needs some more work:
Declare a dependency as usual
libraryDependencies += "org.example" % "rich-util" % "0.1"
Add the source dependency from the command line, overriding the normal dependency automatically in the process
$ sbt
> projects add ../RichUtil
The convention-based approach described in Setting up sbt environment to hack on multiple libraries at once is a special case and would be enabled by this working as well.