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}
Related
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
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
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) => ...
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
I'm trying to mock a method call that takes a call-by-name argument:
import org.scalatest.WordSpec
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
trait Collaborator {
def doSomething(t: => Thing)
}
trait Thing
#RunWith(classOf[JUnitRunner])
class Test extends WordSpec with MockitoSugar {
"The subject under test" should {
"call the collaborator" in {
// setup
val m = mock[Collaborator]
val t = mock[Thing]
// test code: this would actually be invoked by the SUT
m.doSomething(t)
// verify the call
verify(m).doSomething(t)
}
}
}
I'm primarily interested in Mockito since that's what I'm using, but I'd be interested to see whether any of the major mock frameworks is capable of this kind of testing. The Test fails at runtime on the verify line, with an error like
Argument(s) are different! Wanted:
collaborator.doSomething(
($anonfun$apply$3) <function>
);
-> at Test$$anonfun$1$$anonfun$apply$1.apply(Test.scala:27)
Actual invocation has different arguments:
collaborator.doSomething(
($anonfun$apply$2) <function>
);
-> at Test$$anonfun$1$$anonfun$apply$1.apply(Test.scala:24)
If I'm understanding the situation correctly, the compiler is implicitly wrapping t in a nullary function that returns t. The mock framework is then comparing that function to the one produced in the test code, which is equivalent but not equals().
My case is a relatively simple version of the problem, but I think this would be an issue with any higher-order function.
This looks ugly, but hopefully it can help you to find good solution:
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito._
trait Collaborator {
def doSomething(t: => Thing)
}
trait Thing
new MockitoSugar {
// setup
val m = mock[Collaborator]
val t = mock[Thing]
m.doSomething(t)
classOf[Collaborator].getMethod("doSomething", classOf[Function0[_]]).invoke(
verify(m),
new Function0[Thing] {
def apply() = null
override def equals(o: Any): Boolean = t == o.asInstanceOf[Function0[Thing]].apply()
})
}
You can try specs2. In specs2, we "hijack" the Mockito Invocation class to account for byname parameters:
trait ByName { def call(i: =>Int) = i }
val byname = mock[ByName]
byname.call(10)
there was one(byname).call(10)
This problem seems to be specific to by-name invocations because in regular higher order functions you can match against the explicit FunctionX object:
verify(collaborator).somethingElse(any(Function2[String, Thing]))
in the by-name case the wrapping of the argument into a Function0 is done implicitly, and Alexey's answer shows how to invoke the mock with an explicit parameter.
You could write something akin to your own verify which would apply arguments captured by mockito.
Mockito internally records invocation and their arguments with e.g.:
http://code.google.com/p/mockito/source/browse/trunk/src/org/mockito/internal/matchers/CapturingMatcher.java