Skip to content

Instantly share code, notes, and snippets.

View tzachz's full-sized avatar

Tzach Zohar tzachz

View GitHub Profile
@tzachz
tzachz / OffendingLines.scala
Created September 17, 2019 18:37
Mockito gotcha: what went wrong
/* 1 */ val dependency: MyOtherService = mock[MyOtherService]
/* 2 */ when(dependency.getValue(any())).thenAnswer(answerSizeOfInputPlus(2))
/* 3 */ when(dependency.getValue(any())).thenAnswer(answerSizeOfInputPlus(3))
@tzachz
tzachz / MyServiceSpec.scala
Created September 17, 2019 18:27
Mockito gotcha: full test
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 {
@tzachz
tzachz / usecase.scala
Last active September 17, 2019 18:25
Mockito gotcha: usecase
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...
}
@tzachz
tzachz / MyService.scala
Last active September 17, 2019 18:26
Mockito gotcha: Service
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
}
@tzachz
tzachz / AreTasksCompleted.java
Created August 10, 2018 19:08
Functional Collection Manipulation
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 {
@tzachz
tzachz / FinalUsage.scala
Created July 24, 2018 22:05
CompositionFinal
// 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)
}
@tzachz
tzachz / SingleWrappers.scala
Created July 20, 2018 20:37
CompositionPostWhatIf
// 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
@tzachz
tzachz / FirstAttemptInline.scala
Created July 20, 2018 20:31
CompositionPostInline
// 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..
@tzachz
tzachz / ComposedFlipImpl.scala
Last active July 24, 2018 21:57
CompositionPost3
// 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)
}
@tzachz
tzachz / FirstAttempt.scala
Created July 20, 2018 20:02
CompositionPost2
// 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)