What to use instead of symbols in scalatest? - scala

In scalatest, you’re supposed to be able to test boolean properties using symbols like this:
iter shouldBe 'traversableAgain
But this notation have been deprecated in the most recent versions of scala, so now you’re supposed to write:
iter shouldBe Symbol("traversableAgain")
Which is a bit ugly. Is there any better alternative?

Consider BePropertyMatcher which provides type-safe predicate matching syntax
iter should be (traversableAgain)
for example
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.{BePropertyMatchResult, BePropertyMatcher}
import org.scalatest.matchers.should.Matchers
trait CustomMatchers {
val traversableAgain = new BePropertyMatcher[Iterator[_]] {
def apply(left: Iterator[_]): BePropertyMatchResult =
BePropertyMatchResult(left.isTraversableAgain, "isTraversableAgain")
}
}
class BePropertyMatcherExampleSpec extends AnyFlatSpec with Matchers with CustomMatchers {
"BePropertyMatcher" should "provide type-safe checking of predicates" in {
Iterator(42, 11) should be (traversableAgain)
}
}
There is also a related issue Replacement for using symbols as property matchers for 2.13+ #1679

Related

scalatest assert that either is right results in symbol literal is deprecated warning [duplicate]

In scalatest, you’re supposed to be able to test boolean properties using symbols like this:
iter shouldBe 'traversableAgain
But this notation have been deprecated in the most recent versions of scala, so now you’re supposed to write:
iter shouldBe Symbol("traversableAgain")
Which is a bit ugly. Is there any better alternative?
Consider BePropertyMatcher which provides type-safe predicate matching syntax
iter should be (traversableAgain)
for example
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.{BePropertyMatchResult, BePropertyMatcher}
import org.scalatest.matchers.should.Matchers
trait CustomMatchers {
val traversableAgain = new BePropertyMatcher[Iterator[_]] {
def apply(left: Iterator[_]): BePropertyMatchResult =
BePropertyMatchResult(left.isTraversableAgain, "isTraversableAgain")
}
}
class BePropertyMatcherExampleSpec extends AnyFlatSpec with Matchers with CustomMatchers {
"BePropertyMatcher" should "provide type-safe checking of predicates" in {
Iterator(42, 11) should be (traversableAgain)
}
}
There is also a related issue Replacement for using symbols as property matchers for 2.13+ #1679

Why does Mockito verifyNoMoreInteractions has problem with Scala default values

For a mocked class I have a method for which I would like to test whether there are no more interactions then needed, which looks similar to:
def someMethod(someMandatoryParam: Int, canBeDefaultIds: Option[Ids] = None): Future[Failures] = {...}
when I am mocking to invoke this method without the default parameter and I verify it that way:
verify(someClass).someMethod(someInt)
and then check if there was no more interactions:
verifyNoMoreInteractions(someClass)
I am getting an error that here was some unexpected interactions.
But when in implementation I change this method to use None instead of default value and verify:
verify(someClass).someMethod(someInt, None)
verifyNoMoreInteractions(someClass)
It works correctly.
Is there a problem with Mocikto and default values in Scala?
Default arguments is Scala specific feature which Java Mockito is likely not aware of. Consider how Scala code looks after -Xprint:jvm phase
abstract trait SomeClass extends Object {
def someInt(a: Option): Option = a;
<synthetic> def someInt$default$1(): Option = scala.None;
}
Notice how the default argument became just another method someInt$default$1. Try using mockito-scala which is designed with Scala in mind, for example the following test passes
import org.mockito.{ArgumentMatchersSugar, IdiomaticMockito}
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
trait SomeClass {
def someInt(a: Option[Int] = None) = a
}
class MockitoScalaDefaultArgsSpec extends AnyFlatSpec with Matchers with IdiomaticMockito with ArgumentMatchersSugar {
"mockito-scala" should "handle default arguments" in {
val someClass = mock[SomeClass]
someClass.someInt()
someClass.someInt() was called
someClass wasNever calledAgain
}
}

Gen.sequence ignores size of given Traversable

Gen.sequence seems to be ignoring size of given Traversable. Is that by design? I'm using version 1.14.0 with Scala 2.13. Following generator
Gen.sequence[List[Int], Int](List.fill(3)(Gen.const(5)))
sometimes generates List of size 1. What am I missing ?
Sample test
import org.scalacheck.Gen
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{Assertions, FlatSpec, Inside, Inspectors, Matchers, OptionValues}
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
class RuleSpec extends FlatSpec with Matchers with Assertions with OptionValues with Inside with Inspectors with ScalaFutures with ScalaCheckPropertyChecks {
val filterGen = Gen.listOfN(3, Gen.const(5))
val inputGen = Gen.pick(10, 5 to 15).map(_.toList).filter(_.nonEmpty)
"A HasAny rule with partially matching filter" should "validate input" in {
forAll(filterGen, inputGen) { case (filter, input) =>
val result = HasAny(filter: _*).valid(input)
println(s"$result: $filter ${input}\n")
result should be(true)
}
}
}
This might be due to Test Case Minimisation
One interesting feature of ScalaCheck is that if it finds an argument
that falsifies a property, it tries to minimise that argument before
it is reported. This is done automatically when you use the
Prop.property and Prop.forAll methods to create properties, but not if
you use Prop.forAllNoShrink.
Hence try using Prop.forAllNoShrink like so
Prop.forAllNoShrink(filterGen, inputGen) { case (filter, input) => ...
If using ScalaTest's forAll then try the suggestion in Add support for not shrinking values in GeneratorDrivenPropertyChecks #584 by creating the following trait
trait NoShrink {
implicit def noShrink[A]: Shrink[A] = Shrink(_ => Stream.empty)
}
and mix it in the spec like so
class RuleSpec extends FlatSpec ... with ScalaCheckPropertyChecks with NoShrink {
...
forAll(filterGen, inputGen) { case (filter, input) => ...

Scala & ScalaTest operator === conflict

I want to test operator === of Scalaz using ScalaTest.
I have written simply test:
class ComparisonTest extends FunSuite {
test("=== operator of Scalaz") {
assert(1 === 1) // i want to check/test === operator of Scalaz
}
}
Unfortunately within assert of my test, scala picked operator === from ScalaTest. It did not help if I import explicitly:
import scalaz.Scalaz._
import scalaz._
I also tried:
import scalaz.syntax.EqualOps
assert(new EqualOps[Int](1).===(1)) }
but it did not compile:
Error:(10, 12) constructor EqualOps in class EqualOps cannot be accessed in class ComparisonTest
assert(new EqualOps[Int](1).===(1)) }
Is there any way to do such test of Scalaz ===operator within test of FunSuite? (maybe somhow disable === of ScalaTest)
For new EqualOps[Int](1).===(1)) error, you can use implicitly[Equal[Int]].equal(1, 2) to implicitly get Scalaz Equal implementation.
For disable scalatest Equalizer implicit conversion, you can try to override convertToEqualizer method and remove implicit method modifier.
Example:
class ComparisonTest extends FunSuite {
override def convertToEqualizer[T](left: T): Equalizer[T] = new Equalizer(left)
import scalaz._
import Scalaz._
test("=== operator of Scalaz") {
assert(1 === 1) // i want to check/test === operator of Scalaz
}
}
this is a tricky way to achieve this, best way maybe need scalatest change Equalizer inject way, like by import, and we can unimport the implicit like: import Predef.{any2stringadd}

Scalamock: How to get "expects" for Proxy mocks?

I am using Scalamock with ScalaTest, and am trying to mock a Java interface. I currently have:
private val _iface = mock [MyInterface]
now I want to do
_iface expects `someMethod returning "foo" once
But the compiler does not find expects.
I imported org.scalatest._ and org.scalamock.scalatest._. What else am I missing?
First of all, proxy mocks are not supported very well in ScalaMock 3, and I think they will be completely removed in ScalaMock 4. Do you really need to use proxy mocks instead macro mocks?
This should work:
package example
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import org.scalamock.scalatest.proxy.MockFactory
trait MyInterface {
def someMethod : String
}
class MyTest extends FlatSpec with Matchers with MockFactory {
"MyInterface" should "work" in {
val m = mock[MyInterface]
m.expects('someMethod)().returning("foo")
m.someMethod shouldBe "foo"
}
}
If not, please check ScalaMock proxy mocks unit tests for more examples.
I think it should be something more like:
import org.scalamock.scalatest.MockFactory
class MyTest extends FlatSpec with Matchers with MockFactory {
"MyInterface" should "work" in {
val m = mock[MyInterface]
(m.someMethod _).expects().returning("foo")
m.someMethod shouldBe "foo"
}
}
I think the expects arg is expecting the arg to the function
I use scalaMock version 4.1.0, this works for me:
For some trait:
trait MyInterface { def someMethod(n1: Int, n2: Int) }
This should be put into a test
val myInterfaceMock = mock[MyInterface]
myInterfaceMock.someMethod _ expects (1,2)
For more reading: scalaMock Guide, you'll find some examples there