Skip to content

Instantly share code, notes, and snippets.

@noelmarkham
Last active May 26, 2022 14:32
Show Gist options
  • Save noelmarkham/37ec9ce8c33cbf1e65f8 to your computer and use it in GitHub Desktop.
Save noelmarkham/37ec9ce8c33cbf1e65f8 to your computer and use it in GitHub Desktop.
Mocking using Cats
package nm
import cats._
import cats.implicits._
import cats.data.WriterT
object Mocking {
// a bit contrived, use your imagination :-)
def requestThatCallsSomeServices[M[_]: Monad](f: String => M[Int], g: Int => M[Unit])(s: String): M[Unit] = {
for {
i <- f(s)
_ <- g(i - 1)
j <- f(s)
_ <- g(j - 2)
} yield ()
}
def mock = {
type MockFramework[A] = WriterT[Id, List[String], A]
val fMock: String => MockFramework[Int] = s => WriterT.put(s.length)(List(s"Returned ${s.length}"))
val gMock: Int => MockFramework[Unit] = i => WriterT.tell(List(s"Function g received $i"))
val inputString = "Test"
val inputStringLength = inputString.length
val expectation = List(
s"Returned $inputStringLength",
s"Function g received ${inputStringLength - 1}",
s"Returned $inputStringLength",
s"Function g received ${inputStringLength - 2}"
)
val runRequest: MockFramework[Unit] = requestThatCallsSomeServices(fMock, gMock)(inputString)
val (writtenValues, _) = runRequest.run // the second param is what is returned from the function, ie Unit here
println(writtenValues == expectation)
/*
* > console
* [info] Starting scala interpreter...
* [info]
* Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_66).
* Type in expressions to have them evaluated.
* Type :help for more information.
*
* scala> import nm.Mocking._
* import nm.Mocking._
*
* scala> mock
* true
*/
}
/*
And then in your application code:
def realLife = {
val s: String = ???
val f: String => Task[Int] = ???
val g: Int => Task[Unit] = ???
val result: Task[Unit] = requestThatCallsSomeServices(f, g)(s)
// ... and so on
}
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment