This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 1 */ val dependency: MyOtherService = mock[MyOtherService] | |
/* 2 */ when(dependency.getValue(any())).thenAnswer(answerSizeOfInputPlus(2)) | |
/* 3 */ when(dependency.getValue(any())).thenAnswer(answerSizeOfInputPlus(3)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MyServiceSpec extends FlatSpec with Matchers with MockitoSugar with BeforeAndAfter { | |
private val dependency: MyOtherService = mock[MyOtherService] | |
private val underTest = new MyService(dependency) | |
before { // default for most tests: | |
when(dependency.getValue(any())).thenAnswer(answerSizeOfInputPlus(2)) | |
} | |
"MyService.testedMethod" should "return output from getValue plus one" in { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
before { | |
// default for most tests: | |
when(dependency.getValue(any())).thenAnswer(produceDefaultAnswer()) | |
} | |
"MyService.testedMethod" should "do something special" in { | |
// override default for this test: | |
when(dependency.getValue(any())).thenAnswer(produceSpecialAnswer()) | |
// continue test... | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.kenshoo.example | |
class MyService(val dependency: MyOtherService) { | |
def testedMethod(input: String): Int = dependency.getValue(input) + 1 | |
} | |
class MyOtherService() { | |
def getValue(input: String): Int = input.length * 2 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.common.collect.ImmutableList; | |
import java.util.List; | |
import java.util.Optional; | |
import static TasksCompletedExample.TaskStatus.Completed; | |
import static TasksCompletedExample.TaskStatus.Started; | |
import static java.util.stream.Collectors.groupingBy; | |
import static java.util.stream.Collectors.mapping; | |
import static java.util.stream.Collectors.toSet; | |
public class TasksCompletedExample { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Now we can count on flapMap to do the magic! | |
def processRequest(a: A): Future[Result] = { | |
for { | |
b <- f1(a) | |
c <- flip(b.map(f2)) | |
d <- flip(c.map(f3)) | |
r <- flip(d.map(f4)) | |
} yield r.getOrElse[Result](r.left.get) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// If we didn't have Eithers (or generally speaking - wrappers-of-wrappers) - | |
// this would be easy: | |
def processRequest(a: A): Future[Result] = for { | |
b <- f1(a) | |
c <- f2(b) | |
d <- f3(c) | |
r <- f4(d) | |
} yield r |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// first attempt: let's just write it down and make the compiler happy: | |
def processRequest(a: A): Future[Result] = f1(a).flatMap { | |
case Right(b) => f2(b).flatMap { | |
case Right(c) => f3(c).flatMap { | |
case Right(d) => | |
f4(d).map(either => either.getOrElse(either.left.get)) | |
case Left(f) => Future.successful(f) // we "satisfy" Future.flatMap by wrapping | |
// the left result with a successful future | |
} | |
case Left(f) => Future.successful(f) // and again.. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Introduce a flip method: it looks tricky, but as usual it just "follows the types": | |
private def flip[L, R](eitherFuture: Either[L, Future[Either[L, R]]]): Future[Either[L, R]] = { | |
eitherFuture.fold[Future[Either[L, Either[L, R]]]]( | |
left => Future.successful[Either[L, Either[L, R]]](Left(left)), | |
right => right.map(Right(_)) | |
).map(_.joinRight) | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// we'll start by applying f1 and mapping the future result by pattern-matching Left or Right: | |
def processRequest(a: A): Future[Result] = f1(a).flatMap { | |
case Right(b) => getC(b) | |
case Left(f) => Future.successful(f) | |
} | |
// Now we do something similar to the result, this time applying f2: | |
private def getC(b: B): Future[Result] = f2(b).flatMap { | |
case Right(c) => getD(c) | |
case Left(f) => Future.successful(f) |