Combine mocks and ordinary tests within one test class in Scala - scala

Code
Test
package com.utrecht.numbersequences
import org.scalatest.FunSuite
import org.scalatest.BeforeAndAfter
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito._
class NumberSequencesTests extends FunSuite with BeforeAndAfter with MockitoSugar {
test("randomInteger") {
val m = mock[NumberSequences]
when(m.randomInteger(5)).thenReturn(5)
assert(5 === m.randomInteger(5))
}
test("squareRoot") {
assert(NumberSequences.squareRoot(25) === 5)
}
}
Main
package com.utrecht.numbersequences
import scala.collection.immutable.Stream.consWrapper
class NumberSequences {
def randomInteger(a: Int) : Int = {
scala.util.Random.nextInt(a) + 1
}
def squareRoot(a: Double) : Double = {
math.sqrt(a)
}
}
Outcome
Expected
> test
[info] NumberSequencesTests:
[info] - randomInteger
[info] - squareRoot
[info] Passed: Total 2, Failed 0, Errors 0, Passed 2
[success] Total time: 1 s, completed Aug 10, 2014 11:46:44 AM
>
Current
In order to test squareRoot the NumberSequences class needs to be changed into an object. Once this has been done, the squareRoot can be tested, but the mock fails. Once this has been reversed, the mock test passes, but the squareRoot test fails again.
> test
[info] Compiling 1 Scala source to C:\path\to\developme
nt\scalaNumberSequences\target\scala-2.10\test-classes...
[error] C:\path\to\scalaNumberSequences\src
\test\scala\com\utrecht\numbersequences\NumberSequencesTest.scala:16: not found:
value NumberSequences
[error] assert(NumberSequences.squareRoot(25) === 5)
[error] ^
[error] one error found
[error] (test:compile) Compilation failed
[error] Total time: 1 s, completed Aug 10, 2014 11:47:13 AM
>

You have to instantiate a NumberSequences object, since it's a class, not an object or companion object.
assert(new NumberSequences().squareRoot(25) === 5)
To use this syntax:
assert(NumberSequences.squareRoot(25) === 5)
you would need this:
object NumberSequences {
def squareRoot(a: Double) : Double = {
math.sqrt(a)
}
}
But since you need to mock it (in the first test), I would rather use the first solution: instantiating the class.

Related

Scala Play + Slick: How to inject dependencies to Spec tests?

I'm using Scala Play 2.7.x (the project is available here Play-Silhouette-Seed) and would like to test my daos. I have put together this simple one first to check what's the "new pattern" for testing play + slick + guice in 2.7.x:
package models.daos
import java.util.UUID
import org.specs2.mock._
import org.specs2.mutable._
import utils.AwaitUtil
import javax.inject.Inject
import models.generated.Tables.LoginInfoRow
class LoginInfoDaoSpec #Inject() (loginInfoDao: LoginInfoDao) extends Specification with Mockito with AwaitUtil {
"Creating a new LoginInfo" should {
"save it in the empty database" in {
loginInfoDao.create(LoginInfoRow(0, UUID.randomUUID().toString, UUID.randomUUID().toString))
loginInfoDao.findAll.size should beEqualTo(1)
}
}
}
Unfortunately, the guice dependency LoginInfoDao is not being provided to my test and then I get the error:
[play-silhouette-seed] $ testOnly models.daos.LoginInfoDaoSpec
[info] Done compiling.
[error] Can't find a suitable constructor with 0 or 1 parameter for class models.daos.LoginInfoDao
[info] ScalaTest
[info] Run completed in 1 second, 966 milliseconds.
[info] Total number of tests run: 0
[info] Suites: completed 0, aborted 0
[info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0
[info] No tests were executed.
[error] Error: Total 1, Failed 0, Errors 1, Passed 0
How do I get guice loading the needed modules for my test-cases?
A module is defined as:
class SilhouetteModule extends AbstractModule with ScalaModule {
override def configure() {
// ...
bind[LoginInfoDao].to[LoginInfoDaoImpl]
// ...
}
}
and I have an application.test.conf available defined as:
include "application.conf"
slick.dbs {
default {
profile="slick.jdbc.MySQLProfile$"
db.driver="com.mysql.cj.jdbc.Driver"
db.url="jdbc:mysql://localhost:3306/mytestdb?useUnicode=true&searchpath=public&serverTimezone=CET"
db.user="dev"
db.password="12345"
}
}
You should use another database for testing, H2 is the common choice.
class Module extends AbstractModule with ScalaModule {
...
}
With that name you need to let play know there is a Module to load, if you call it Module, it automatically know what to load and should work just fine (if you only need 1 module in testing)
If that doesn't work let me know

`eventually` not found in scala.rx

Here is an example from the scala.rx doc:
package tutorial.webapp
import rx.core.{Rx, Var}
import rx._
import rx.ops._
import scala.concurrent.Promise
import scala.concurrent.duration._
import scala.scalajs.js.JSApp
import scala.scalajs.js.annotation.JSExport
import scala.concurrent.ExecutionContext.Implicits.global
/**
* Created by IDEA on 29/10/15.
*/
object RxAddtionalOps extends JSApp {
#JSExport
override def main(): Unit = {
mapDemo
filterDemo
asyncDemo
async2
timer1
}
def delay1: Unit = {
val a = Var(10)
val b = a.delay(250 millis)
a() = 5
println(b())
eventually{
println(b)
}
}
}
I got this error on sbt when compiling:
[error] /Users/kaiyin/personal_config_bin_files/workspace/scalajsHandson/src/main/scala/tutorial/webapp/RxAddtionalOps.scala:43: not found: value eventually
[error] eventually{
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 1 s, completed 30 oct. 2015 11:15:07
Where does the eventually function come from? Am I missing any imports?
It's defined in utest, which is a author's framework for tests. Since it's a test dependency it doesn't come bundled with scalarx. BTW, the very same functionality presented in scalatest.

Problems importing scala for scalatest

I'm new to scala but I'm trying to add some tests to a simple file. The problem is that when I try to import the object into the test I get "error: not found: value"
PerfectNumberImperative.scala
package perfectImperative
package object perfectImperative{
def main(args: Array[String]){
perfectImperative(args(0).toInt)
}
def perfectImperative(input: Int): Boolean = {
var evaluation = (for (possibleFactor <-1 to input if (input % possibleFactor == 0)) yield possibleFactor).sum == input*2
return evaluation
}
}
PerfectNumberSpec.scala
import org.scalatest.FlatSpec
import perfectImperative._
class PerfectNumberSpec extends FlatSpec {
it should "return true for 6" in {
assert(perfectImperative.perfectImperative(6))
}
}
[error] C:\Users\Daniel\PerfectNumbersScala\src\test\scala\PerfectNumberSpec.scala:2: not found: object perfectImperative
[error] import perfectImperative._
[error] ^
[error] C:\Users\Daniel\PerfectNumbersScala\src\test\scala\PerfectNumberSpec.scala:6: not found: value perfectImperative
[error] assert(perfectImperative.perfectImperative(6))
[error] ^
[error] two errors found
[error] (test:compileIncremental) Compilation failed
[error] Total time: 2 s, completed Sep 16, 2015 2:30:38 AM
I would appreciate if someone could point me in the right direction.

Request was neither completed nor rejected within 1 second Scala Spray Testing

I currently testing a web service, and I keep on running into an error where the web service test is failing because it is timing out. I'm trying to extends that timeout to be 5 seconds long. I'm trying to mimic a solution that some one posted on the Scala Spray google groups forum to no avail. Here is the code I am trying to use in my test:
import akka.testkit._
import akka.actor.ActorSystem
import com.github.nfldb.config.{NflDbApiActorSystemConfig, NflDbApiDbConfigTest}
import org.scalatest.MustMatchers
import org.specs2.mutable.Specification
import spray.testkit.Specs2RouteTest
import spray.routing.HttpService
import spray.http.StatusCodes._
import spray.json.DefaultJsonProtocol._
import spray.httpx.SprayJsonSupport._
import concurrent.duration._
/**
* Created by chris on 8/25/15.
*/
class NflPlayerScoringSvcTest extends Specification with Specs2RouteTest with NflPlayerScoringService
with NflDbApiDbConfigTest with NflDbApiActorSystemConfig {
import PlayerScoreProtocol.playerScoreProtocol
implicit def actorRefFactory = actorSystem
implicit def default(system: ActorSystem = actorSystem) = RouteTestTimeout(new DurationInt(5).second.dilated)
"NflPlayerScoringSvc" should {
"return hello" in {
Get("/hello") ~> nflPlayerScoringServiceRoutes ~> check {
responseAs[String] must contain("Say hello")
}
}
"calculate a player's score for a given week" in {
import PlayerScoreProtocol.playerScoreProtocol
Get("/playerScore?playerId=00-0031237&gsisId=2015081551") ~> nflPlayerScoringServiceRoutes ~> check {
val playerScore : DfsNflScoringEngineComponent.PlayerScore = responseAs[DfsNflScoringEngineComponent.PlayerScore]
playerScore.playerId must be ("00-0031237")
}
}
}
}
and here is the error that I am receiving:
> test-only *NflPlayerScoringSvcTest*
[info] Compiling 1 Scala source to /home/chris/dev/suredbits-dfs/target/scala-2.11/test-classes...
15:54:54.639 TKD [com-suredbits-dfs-nfl-scoring-NflPlayerScoringSvcTest-akka.actor.default-dispatcher-4] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
15:54:55.158 TKD [NflDbApiActorSystemConfig-akka.actor.default-dispatcher-2] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
15:54:55.228 TKD [NflDbApiActorSystemConfig-akka.actor.default-dispatcher-2] INFO test test test - Trying to find score for player: 00-0031237 and optional gsisId: Some(2015081551)
15:54:55.228 TKD [NflDbApiActorSystemConfig-akka.actor.default-dispatcher-2] INFO test test test - Searching for player 00-0031237 with optional game: Some(2015081551)
15:54:55.268 TKD [NflDbApiActorSystemConfig-akka.actor.default-dispatcher-4] INFO c.s.d.n.s.NflPlayerScoringSvcTest - Creating database for class com.suredbits.dfs.nfl.scoring.NflPlayerScoringSvcTest
[info] NflPlayerScoringSvcTest
[info]
[info] NflPlayerScoringSvc should
[info] + return hello
[info] x calculate a player's score for a given week
[error] Request was neither completed nor rejected within 1 second (NflPlayerScoringSvcTest.scala:33)
[info]
[info]
[info] Total for specification NflPlayerScoringSvcTest
[info] Finished in 1 second, 310 ms
[info] 2 examples, 1 failure, 0 error
[info] ScalaTest
[info] Run completed in 3 seconds, 455 milliseconds.
[info] Total number of tests run: 0
[info] Suites: completed 0, aborted 0
[info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0
[info] No tests were executed.
[error] Failed: Total 2, Failed 1, Errors 0, Passed 1
[error] Failed tests:
[error] com.suredbits.dfs.nfl.scoring.NflPlayerScoringSvcTest
[error] (test:testOnly) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 11 s, completed Aug 25, 2015 3:54:56 PM
> 15:54:56.799 TKD [NflDbApiActorSystemConfig-akka.actor.default-dispatcher-2] INFO c.s.d.n.s.NflPlayerScoringSvcTest - Calculating score for game: NflGame(2015081551,Some(56772),2015-08-16T00:00:00.000Z,NflPreSeasonWeek1,Saturday,2015,Preseason,true,HomeTeam(MIN,26,9,14,3,0,2),AwayTeam(TB,16,3,6,7,0,1),2015-05-22T21:54:43.143Z,2015-08-16T17:29:01.729Z) and player: NflPlayer(00-0031237,Some(T.Bridgewater),Some(Teddy Bridgewater),Some(Teddy),Some(Bridgewater),MIN,QB,Some(2543465),Some(http://www.nfl.com/player/teddybridgewater/2543465/profile),Some(5),Some(11/10/1992),Some(Louisville),Some(2),Some(74),Some(215),Active)
can anyone provide any insight as what to what I can do to extend the time timeout time on Scala Spray?
Here is the solution
implicit def default(implicit system: ActorSystem) = RouteTestTimeout(new DurationInt(5).second.dilated(system))
I have to explicitly pass for system parameter to the dilated method because of implicit conflicts in Scala.
Similar to the previous answer, but a bit shorter
implicit def default(implicit system: ActorSystem) = RouteTestTimeout(5.seconds)
Here is the change which you will need to make -
implicit def default(implicit system: ActorSystem): RouteTestTimeout = RouteTestTimeout(new DurationInt(8).second.dilated(system))

TDD Getters and Setters in Scala

Test
package com.utrecht.numbersequences
import org.scalatest.FunSuite
import org.scalatest.BeforeAndAfter
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito._
class NumberSequencesTests extends FunSuite with BeforeAndAfter with MockitoSugar {
test("testCity") {
NumberSequences.city_("utrecht")
assert("utrecht" === NumberSequences.city())
}
}
Code
package com.utrecht.numbersequences
import scala.collection.immutable.Stream.consWrapper
object NumberSequences {
var _city: String = null
def city_=(_city:String) = this._city = _city
def city = this._city
}
Outcome
value not a member of object
not enough arguments for method apply: (index: Int)Char in class StringOps
test
[info] Compiling 1 Scala source to C:\path\to\developme
nt\scalaNumberSequences\target\scala-2.10\test-classes...
[error] C:\path\to\development\scalaNumberSequences\src
\test\scala\com\utrecht\numbersequences\NumberSequencesTest.scala:32: value city
_ is not a member of object com.utrecht.numbersequences.NumberSequences
[error] NumberSequences.city_("utrecht")
[error] ^
[error] C:\path\to\development\scalaNumberSequences\src
\test\scala\com\utrecht\numbersequences\NumberSequencesTest.scala:33: not enough
arguments for method apply: (index: Int)Char in class StringOps.
[error] Unspecified value parameter index.
[error] assert("utrecht" === NumberSequences.city())
[error] ^
[error] two errors found
[error] (test:compile) Compilation failed
[error] Total time: 1 s, completed Aug 10, 2014 5:52:16 PM
NumberSequences.city_=("utrecht")
//OR
NumberSequences.city = "utrecht"
but not:
NumberSequences.city_("utrecht") // city_ is not a method existing in the object