-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathMockExampleSpec.scala
154 lines (141 loc) · 6.02 KB
/
MockExampleSpec.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package zio.examples.test
import zio.test.Assertion._
import zio.test.mock.Expectation.{value, valueF}
import zio.test.mock.{MockClock, MockConsole, MockRandom}
import zio.test.{DefaultRunnableSpec, Spec, TestFailure, TestSuccess, assertM}
import zio.{ZIO, clock, console, random}
import java.io.IOException
object MockExampleSpec extends DefaultRunnableSpec {
def spec: Spec[Any, TestFailure[IOException], TestSuccess] = suite("suite with mocks")(
testM("expect no call") {
def maybeConsole(invokeConsole: Boolean) =
ZIO.when(invokeConsole)(console.putStrLn("foo"))
val maybeTest1 = maybeConsole(false).provideLayer(MockConsole.empty)
val maybeTest2 = maybeConsole(true).provideLayer(MockConsole.PutStrLn(equalTo("foo")))
assertM(maybeTest1)(isUnit) *> assertM(maybeTest2)(isUnit)
},
testM("expect no call on skipped branch") {
def branchingProgram(predicate: Boolean) =
ZIO.succeed(predicate).flatMap {
case true => console.getStrLn
case false => clock.nanoTime
}
val clockLayer = MockClock.NanoTime(value(42L)).toLayer
val noCallToConsole = branchingProgram(false).provideLayer(MockConsole.empty ++ clockLayer)
val consoleLayer = MockConsole.GetStrLn(value("foo")).toLayer
val noCallToClock = branchingProgram(true).provideLayer(MockClock.empty ++ consoleLayer)
assertM(noCallToConsole)(equalTo(42L)) *> assertM(noCallToClock)(equalTo("foo"))
},
testM("expect no call on multiple skipped branches") {
def branchingProgram(predicate: Boolean) =
ZIO.succeed(predicate).flatMap {
case true => console.getStrLn
case false => clock.nanoTime
}
def composedBranchingProgram(p1: Boolean, p2: Boolean) =
branchingProgram(p1) &&& branchingProgram(p2)
val clockLayer = (MockClock.NanoTime(value(42L)) andThen MockClock.NanoTime(value(42L))).toLayer
val noCallToConsole = composedBranchingProgram(false, false)
.provideLayer(MockConsole.empty ++ clockLayer)
val consoleLayer = (MockConsole.GetStrLn(value("foo")) andThen MockConsole.GetStrLn(value("foo"))).toLayer
val noCallToClock = composedBranchingProgram(true, true)
.provideLayer(MockClock.empty ++ consoleLayer)
assertM(noCallToConsole)(equalTo((42L, 42L))) *> assertM(noCallToClock)(equalTo(("foo", "foo")))
},
testM("should fail if call for unexpected method") {
def maybeConsole(invokeConsole: Boolean) =
ZIO.when(invokeConsole)(console.putStrLn("foo"))
val maybeTest1 = maybeConsole(true).provideLayer(MockConsole.empty)
val maybeTest2 = maybeConsole(false).provideLayer(MockConsole.PutStrLn(equalTo("foo")))
assertM(maybeTest1)(isUnit) *> assertM(maybeTest2)(isUnit)
},
testM("expect call returning output") {
val app = clock.nanoTime
val env = MockClock.NanoTime(value(1000L))
val out = app.provideLayer(env)
assertM(out)(equalTo(1000L))
},
testM("expect call with input satisfying assertion") {
val app = console.putStrLn("foo")
val env = MockConsole.PutStrLn(equalTo("foo"))
val out = app.provideLayer(env)
assertM(out)(isUnit)
},
testM("expect call with input satisfying assertion and transforming it into output") {
val app = random.nextIntBounded(1)
val env = MockRandom.NextIntBounded(equalTo(1), valueF(_ + 41))
val out = app.provideLayer(env)
assertM(out)(equalTo(42))
},
testM("expect call with input satisfying assertion and returning output") {
val app = random.nextIntBounded(1)
val env = MockRandom.NextIntBounded(equalTo(1), value(42))
val out = app.provideLayer(env)
assertM(out)(equalTo(42))
},
testM("expect call for overloaded method") {
val app = random.nextInt
val env = MockRandom.NextInt(value(42))
val out = app.provideLayer(env)
assertM(out)(equalTo(42))
},
testM("expect calls from multiple modules") {
val app =
for {
n <- random.nextInt
_ <- console.putStrLn(n.toString)
} yield ()
val env = MockRandom.NextInt(value(42)) andThen MockConsole.PutStrLn(equalTo("42"))
val out = app.provideLayer(env)
assertM(out)(isUnit)
},
testM("expect repeated calls") {
val app = random.nextInt *> random.nextInt
val env = MockRandom.NextInt(value(42)).repeats(1 to 3)
val out = app.provideLayer(env)
assertM(out)(equalTo(42))
},
testM("expect all of calls, in sequential order") {
val app = random.nextInt *> random.nextLong
val env = MockRandom.NextInt(value(42)) andThen MockRandom.NextLong(value(42L))
val out = app.provideLayer(env)
assertM(out)(equalTo(42L))
},
testM("expect all of calls, in any order") {
val app = random.nextLong *> random.nextInt
val env = MockRandom.NextInt(value(42)) and MockRandom.NextLong(value(42L))
val out = app.provideLayer(env)
assertM(out)(equalTo(42))
},
testM("expect one of calls") {
val app = random.nextLong
val env = MockRandom.NextInt(value(42)) or MockRandom.NextLong(value(42L))
val out = app.provideLayer(env)
assertM(out)(equalTo(42L))
},
testM("failure if invalid method") {
val app = random.nextInt
val env = MockRandom.NextLong(value(42L))
val out = app.provideLayer(env)
assertM(out)(equalTo(42))
},
testM("failure if invalid arguments") {
val app = console.putStrLn("foo")
val env = MockConsole.PutStrLn(equalTo("bar"))
val out = app.provideLayer(env)
assertM(out)(isUnit)
},
testM("failure if unmet expectations") {
val app = random.nextInt
val env = MockRandom.NextInt(value(42)) andThen MockRandom.NextInt(value(42))
val out = app.provideLayer(env)
assertM(out)(equalTo(42))
},
testM("failure if unexpected calls") {
val app = random.nextInt *> random.nextLong
val env = MockRandom.NextInt(value(42))
val out = app.provideLayer(env)
assertM(out)(equalTo(42L))
}
)
}