1 module mocked.tests.mocking; 2 3 import dshould; 4 import mocked; 5 import std.typecons; 6 7 @("mocks functions with one argument") 8 unittest 9 { 10 static class Dependency 11 { 12 string call(string phrase) 13 { 14 return phrase; 15 } 16 } 17 with (Mocker()) 18 { 19 auto dependency = mock!Dependency; 20 21 dependency.expect.call("Noch ein Jahrhundert Zeitungen") 22 .returns("und alle Worte stinken"); 23 24 dependency.call("Noch ein Jahrhundert Zeitungen").should 25 .equal("und alle Worte stinken"); 26 } 27 } 28 29 @("mocks functions without arguments") 30 unittest 31 { 32 enum int expected = 10; 33 34 with (Mocker()) 35 { 36 auto dependency = mock!Object; 37 38 dependency.expect.toHash.returns(expected); 39 40 dependency.toHash.should.equal(expected); 41 } 42 } 43 44 @("mocks overloaded functions") 45 unittest 46 { 47 static class Dependency 48 { 49 int call(int number) 50 { 51 return number; 52 } 53 54 string call(string phrase) 55 { 56 return phrase; 57 } 58 } 59 with (Mocker()) 60 { 61 auto dependency = mock!Dependency; 62 63 dependency.expect.call("Die beste Maske, die wir tragen") 64 .returns("ist unser eigenes Gesicht"); 65 66 dependency.call("Die beste Maske, die wir tragen").should 67 .equal("ist unser eigenes Gesicht"); 68 } 69 } 70 71 @("mocks overloaded functions with the same return type") 72 unittest 73 { 74 static class Dependency 75 { 76 string call(char character) 77 { 78 return [character]; 79 } 80 81 string call(string phrase) 82 { 83 return phrase; 84 } 85 } 86 with (Mocker()) 87 { 88 auto dependency = mock!Dependency; 89 90 dependency.expect.call("Wenn dein Werk den Mund aufthut") 91 .returns("sollst du selber das Maul halten"); 92 93 dependency.call("Wenn dein Werk den Mund aufthut").should 94 .equal("sollst du selber das Maul halten"); 95 } 96 } 97 98 @("keeps original behavior") 99 unittest 100 { 101 static class Dependency 102 { 103 string identity(string phrase) 104 { 105 return phrase; 106 } 107 } 108 with (Mocker()) 109 { 110 auto dependency = mock!Dependency; 111 112 dependency.expect.identity("Jedes Wort ist ein Vorurtheil.") 113 .passThrough; 114 115 dependency.identity("Jedes Wort ist ein Vorurtheil.").should 116 .equal("Jedes Wort ist ein Vorurtheil."); 117 } 118 } 119 120 @("ignores arguments") 121 unittest 122 { 123 static class Dependency 124 { 125 string identity(string phrase) 126 { 127 return phrase; 128 } 129 } 130 with (Mocker()) 131 { 132 auto dependency = mock!Dependency; 133 134 dependency.expect.identity.returns("die nicht durch das Glas kann"); 135 136 dependency.identity("Die Fliege").should 137 .equal("die nicht durch das Glas kann"); 138 } 139 } 140 141 @("ignores final functions") 142 unittest 143 { 144 static class Dependency 145 { 146 final string say(string) 147 { 148 return "Die Alten lasen laut."; 149 } 150 } 151 with (Mocker()) 152 { 153 auto dependency = mock!Dependency; 154 155 dependency.say(null).should.equal("Die Alten lasen laut."); 156 } 157 } 158 159 @("mocks functions with two arguments") 160 unittest 161 { 162 static class Dependency 163 { 164 string say(string, string) 165 { 166 return null; 167 } 168 } 169 with (Mocker()) 170 { 171 auto dependency = mock!Dependency; 172 173 dependency.expect.say("Derselbe Text", "erlaubt unzählige Auslegungen:") 174 .returns(q{es giebt keine "richtige" Auslegung..}); 175 176 dependency.say("Derselbe Text", "erlaubt unzählige Auslegungen:").should 177 .equal(q{es giebt keine "richtige" Auslegung..}); 178 } 179 } 180 181 @("checks consecutive calls") 182 unittest 183 { 184 static class Dependency 185 { 186 string say(string phrase) 187 { 188 return phrase; 189 } 190 } 191 with (Mocker()) 192 { 193 auto dependency = mock!Dependency; 194 195 dependency.expect.say(q{Die "wahre Welt",}) 196 .returns("wie immer auch man sie bisher concipirt hat, -"); 197 198 dependency.expect.say("sie war immer") 199 .returns("die scheinbare Welt noch einmal."); 200 201 dependency.say(q{Die "wahre Welt",}).should 202 .equal("wie immer auch man sie bisher concipirt hat, -"); 203 204 dependency.say("sie war immer").should 205 .equal("die scheinbare Welt noch einmal."); 206 } 207 } 208 209 @("mocks classes with constructors") 210 unittest 211 { 212 static class Dependency 213 { 214 string phrase; 215 216 public this(string phrase) 217 { 218 this.phrase = phrase; 219 } 220 221 public string saySomething() 222 { 223 return this.phrase; 224 } 225 } 226 with (Mocker()) 227 { 228 auto dependency = mock!Dependency("Alea iacta est."); 229 230 dependency.expect.saySomething().passThrough; 231 232 dependency.saySomething().should.equal("Alea iacta est."); 233 } 234 } 235 236 @("mocks void functions") 237 unittest 238 { 239 static class Dependency 240 { 241 void method() 242 { 243 } 244 } 245 static assert(is(typeof(Mocker().mock!Dependency()))); 246 } 247 248 @("mocks classes with overloaded constructors") 249 unittest 250 { 251 import std.string : join, outdent, strip; 252 253 static class Dependency 254 { 255 string phrase; 256 257 public this(string phrase) 258 { 259 this.phrase = phrase; 260 } 261 262 public this(string part1, string part2) 263 { 264 this.phrase = [part1, part2].join('\n'); 265 } 266 267 public string say() 268 { 269 return this.phrase; 270 } 271 } 272 with (Mocker()) 273 { 274 auto dependency = mock!Dependency("Kaum seid ihr geboren,", 275 "so fangt ihr auch schon an zu sterben."); 276 277 dependency.expect.say().passThrough; 278 279 dependency.say.should.equal(r" 280 Kaum seid ihr geboren, 281 so fangt ihr auch schon an zu sterben. 282 ".outdent.strip); 283 } 284 } 285 286 @("allows to disable the constructor") 287 unittest 288 { 289 static class Dependency 290 { 291 public this(string) 292 { 293 } 294 } 295 static assert(is(typeof(Mocker().mock!Dependency()))); 296 } 297 298 @("allows arbitrary actions") 299 unittest 300 { 301 enum string expected = "Nihil est in intellectu, quod non prius fuerit in sensibus"; 302 static class Dependency 303 { 304 void setPhrase() 305 { 306 } 307 } 308 309 string phrase; 310 Mocker mocker; 311 auto dependency = mocker.mock!Dependency(); 312 313 dependency.expect.setPhrase().action(() { 314 phrase = expected; 315 }); 316 317 dependency.setPhrase(); 318 319 phrase.should.equal(expected); 320 } 321 322 @("propagates the value returned by an action") 323 unittest 324 { 325 enum string expected = "Auf seine Fehler säen."; 326 static class Dependency 327 { 328 string phrase() 329 { 330 return null; 331 } 332 } 333 334 Mocker mocker; 335 auto dependency = mocker.mock!Dependency; 336 337 dependency.expect.phrase().action(() => expected); 338 339 dependency.phrase.should.equal(expected); 340 } 341 342 @(".action inherits nothrow from the mocked method") 343 unittest 344 { 345 static class Dependency 346 { 347 void act() pure @safe 348 { 349 } 350 } 351 alias action = () pure @safe { 352 throw new Exception("Von sich absehen ist nöthig um gut - zu sehen."); 353 }; 354 Mocker mocker; 355 auto dependency = mocker.mock!Dependency; 356 357 static assert(is(typeof(dependency.expect.act().action(action)))); 358 } 359 360 @("arguments can be const objects") 361 unittest 362 { 363 interface A 364 { 365 void func(const Object); 366 } 367 Mocker mocker; 368 369 mocker.mock!A(); 370 } 371 372 @("supports struct with immutable members as arguments") 373 unittest 374 { 375 static struct S 376 { 377 private immutable string s; 378 } 379 static class Dependency 380 { 381 void withDefaultParameter(S) 382 { 383 } 384 } 385 static assert(is(typeof(Mocker().mock!Dependency()))); 386 } 387 388 @("supports default parameters") 389 unittest 390 { 391 enum string expected = "simplex sigillum veri"; 392 393 static class Dependency 394 { 395 void say(string = expected) 396 { 397 } 398 } 399 Mocker mocker; 400 401 auto mocked = mocker.mock!Dependency; 402 403 mocked.expect.say(); 404 405 mocked.say(expected); 406 } 407 408 @("can mock functions with more than 2 parameters") 409 unittest 410 { 411 static class Dependency 412 { 413 void say(string, string, string) 414 { 415 } 416 } 417 Mocker mocker; 418 static assert(is(typeof(mocker.mock!Dependency()))); 419 }