1 module mocked.tests.alien; 2 3 import dshould; 4 import mocked; 5 import unit_threaded.attrs : ShouldFail; 6 7 version (unittest) 8 { 9 class Templated(T) 10 { 11 } 12 13 interface IM 14 { 15 void bar(); 16 } 17 18 class ConstructorArg 19 { 20 int a; 21 22 this(int i) 23 { 24 this.a = i; 25 } 26 27 int getA() 28 { 29 return this.a; 30 } 31 } 32 33 class SimpleObject 34 { 35 this() 36 { 37 } 38 39 void print() 40 { 41 import std.stdio : writeln; 42 43 writeln(toString()); 44 } 45 } 46 47 interface IRM 48 { 49 IM get(); 50 void set(IM im); 51 } 52 53 interface IFace 54 { 55 void foo(string s); 56 } 57 58 class Smthng : IFace 59 { 60 void foo(string) 61 { 62 } 63 } 64 65 class HasMember 66 { 67 int member; 68 } 69 70 interface VirtualFinal 71 { 72 int makeVir(); 73 } 74 75 class Dependency 76 { 77 private int[] arr = [1, 2]; 78 private int index = 0; 79 public int foo() 80 { 81 return arr[index++]; 82 } 83 } 84 85 class TakesFloat 86 { 87 public void foo(float) 88 { 89 } 90 } 91 92 class TestClass 93 { 94 string test() 95 { 96 return "test"; 97 } 98 99 string test1() 100 { 101 return "test 1"; 102 } 103 104 string test2() 105 { 106 return "test 2"; 107 } 108 109 int test_int(int i) 110 { 111 return i; 112 } 113 } 114 } 115 116 @("nontemplated mock") 117 unittest 118 { 119 Mocker().mock!(Object)(); 120 } 121 122 @("templated mock") 123 unittest 124 { 125 static assert(is(typeof(Mocker().mock!(Templated!(int))()))); 126 } 127 128 @("interface mock") 129 unittest 130 { 131 static assert(is(typeof(Mocker().mock!IM()))); 132 } 133 134 @("constructor argument") 135 unittest 136 { 137 Mocker mocker; 138 139 static assert(is(typeof(mocker.mock!(ConstructorArg)(4)))); 140 } 141 142 @("unexpected call") 143 unittest 144 { 145 Mocker mocker; 146 TestClass cl = mocker.mock!(TestClass); 147 148 cl.test.should.throwA!UnexpectedCallError; 149 mocker.verify; 150 } 151 152 @ShouldFail("expect") 153 unittest 154 { 155 Mocker mocker; 156 auto cl = mocker.mock!(TestClass); 157 cl.expect.test().repeat(0).returns("mrow?"); 158 159 cl.test; 160 } 161 162 @("repeat single") 163 unittest 164 { 165 Mocker mocker; 166 auto cl = mocker.mock!(TestClass); 167 cl.expect.test().repeat(2).returns("foom?"); 168 169 cl.test; 170 cl.test; 171 172 cl.test.should.throwAn!UnexpectedCallError; 173 } 174 175 @ShouldFail("repository match counts") 176 unittest 177 { 178 Mocker mocker; 179 auto cl = mocker.mock!TestClass; 180 181 cl.expect.test().repeat(2).returns("mew."); 182 183 mocker.verify(); 184 } 185 186 @("delegate payload") 187 unittest 188 { 189 bool calledPayload = false; 190 Mocker mocker; 191 auto obj = mocker.mock!SimpleObject; 192 193 obj.expect.print().action({ calledPayload = true; }); 194 195 obj.print; 196 197 calledPayload.should.be(true); 198 } 199 200 @("delegate payload with mismatching parameters") 201 unittest 202 { 203 Mocker mocker; 204 auto obj = mocker.mock!SimpleObject; 205 206 static assert(!is(typeof(obj.expect.print().action((int) {})))); 207 } 208 209 @("exception payload") 210 unittest 211 { 212 Mocker mocker; 213 auto obj = mocker.mock!(SimpleObject); 214 215 enum string msg = "divide by cucumber error"; 216 obj.expect.print().throws(new Exception(msg)); 217 218 obj.print.should.throwAn!Exception.where.msg.should.equal(msg); 219 } 220 221 @("passthrough") 222 unittest 223 { 224 Mocker mocker; 225 auto cl = mocker.mock!(TestClass); 226 cl.expect.test().passThrough; 227 228 string str = cl.test; 229 str.should.equal("test"); 230 } 231 232 @("class with constructor init check") 233 unittest 234 { 235 Mocker mocker; 236 auto obj = mocker.mock!ConstructorArg(4); 237 238 obj.expect.getA().passThrough; 239 240 obj.getA().should.equal(4); 241 } 242 243 @("associative arrays") 244 unittest 245 { 246 Mocker mocker; 247 248 auto mock = mocker.mock!(Object); 249 mock.expect.toHash.passThrough().repeatAny; 250 mock.expect.opEquals.passThrough().repeatAny; 251 252 auto obj = mock.get; 253 254 int[Object] i; 255 i[obj] = 5; 256 int j = i[obj]; 257 } 258 259 @("mock interface") 260 unittest 261 { 262 Mocker mocker; 263 auto obj = mocker.mock!IFace; 264 265 obj.expect.foo("hallo"); 266 267 obj.get.foo("hallo"); 268 269 mocker.verify; 270 } 271 272 @("cast mock to interface") 273 unittest 274 { 275 Mocker mocker; 276 auto obj = mocker.mock!Smthng; 277 278 obj.expect.foo("hallo"); 279 280 obj.get.foo("hallo"); 281 282 mocker.verify; 283 } 284 285 @("cast mock to interface") 286 unittest 287 { 288 Mocker mocker; 289 auto obj = mocker.mock!Smthng; 290 291 obj.expect.foo("hallo"); 292 293 obj.foo("hallo"); 294 295 mocker.verify; 296 } 297 298 @("return user-defined type") 299 unittest 300 { 301 Mocker mocker; 302 303 auto objBuilder = mocker.mock!IRM; 304 auto obj = objBuilder.get; 305 306 auto imBuilder = mocker.mock!IM; 307 auto im = imBuilder.get; 308 309 objBuilder.expect.get().returns(im); 310 objBuilder.expect.set(im); 311 312 obj.get.should.be(im); 313 obj.set(im); 314 mocker.verify; 315 } 316 317 @("return user-defined type") 318 unittest 319 { 320 Mocker mocker; 321 mocker.mock!HasMember; 322 } 323 324 @("returning different values on the same expectation") 325 unittest 326 { 327 Mocker mocker; 328 auto dependency = mocker.mock!Dependency; 329 330 //mocker.ordered; 331 dependency.expect.foo.returns(1); 332 dependency.expect.foo.returns(2); 333 334 dependency.foo.should.equal(1); 335 dependency.foo.should.equal(2); 336 337 mocker.verify; 338 } 339 340 @("customArgsComparator") 341 unittest 342 { 343 import std.math : abs; 344 345 enum float argument = 1.0f; 346 347 auto mocker = configure!(Comparator!((float a, float b) => abs(a - b) < 0.1f)); 348 auto dependency = mocker.mock!TakesFloat; 349 dependency.expect.foo(argument).repeat(2); 350 351 // custom comparison example - treat similar floats as equals 352 dependency.foo(1.01); 353 dependency.foo(1.02); 354 }