1 module mocked.tests.stub; 2 3 import dshould; 4 import mocked; 5 import unit_threaded.attrs : ShouldFail; 6 7 @("class can be stubbed") 8 unittest 9 { 10 static class Dependency 11 { 12 bool isEven(int number) 13 { 14 return (number & 1) == 0; 15 } 16 } 17 Mocker mocker; 18 auto stubbed = mocker.stub!Dependency; 19 20 stubbed.stub.isEven(6).returns(false); 21 stubbed.stub.isEven(5).returns(true); 22 23 Dependency dependency = stubbed.get; 24 25 dependency.isEven(5).should.equal(true); 26 dependency.isEven(6).should.equal(false); 27 } 28 29 @("stubs classes with an constructor") 30 unittest 31 { 32 static class Dependency 33 { 34 string phrase; 35 36 public this(string phrase) 37 { 38 this.phrase = phrase; 39 } 40 41 public string saySomething() 42 { 43 return this.phrase; 44 } 45 } 46 auto dependency = Mocker().stub!Dependency("Alea iacta est."); 47 48 dependency.stub.saySomething().passThrough; 49 50 dependency.saySomething().should.equal("Alea iacta est."); 51 } 52 53 @("can use custom comparator") 54 unittest 55 { 56 import std.math : abs; 57 58 static class Dependency 59 { 60 public bool call(float) 61 { 62 return false; 63 } 64 } 65 66 alias approxComparator = (float a, float b) { 67 return abs(a - b) <= 0.1; 68 }; 69 auto mocker = configure!(Comparator!approxComparator); 70 auto builder = mocker.stub!Dependency; 71 72 builder.stub.call(1.01).returns(true); 73 74 auto stub = builder.get; 75 76 stub.call(1.02).should.be(true); 77 } 78 79 @("can configure custom comparator with type") 80 unittest 81 { 82 import std.math : abs; 83 84 static class Dependency 85 { 86 public bool call(float) 87 { 88 return false; 89 } 90 91 public bool call(int) 92 { 93 return false; 94 } 95 } 96 97 alias approxComparator = (float a, float b) { 98 return abs(a - b) <= 0.1; 99 }; 100 alias absComparator = (int a, int b) { 101 return abs(a) == abs(b); 102 }; 103 Configure!(approxComparator, absComparator) mocker; 104 auto builder = mocker.stub!Dependency; 105 106 builder.stub.call(1.01).returns(true); 107 builder.stub.call(-1).returns(true); 108 109 auto stub = builder.get; 110 111 stub.call(1.02).should.be(true); 112 stub.call(1).should.be(true); 113 } 114 115 @("stubs const methods") 116 unittest 117 { 118 interface I 119 { 120 public bool isI(string) const; 121 } 122 Mocker mocker; 123 124 static assert(is(typeof(mocker.stub!I()))); 125 } 126 127 @("overrides returned value") 128 unittest 129 { 130 enum string leibniz = "Unsere Welt ist die beste aller möglichen Welten"; 131 enum string schopenhauer = 132 "Unsere Welt ist die schlechteste aller möglichen Welten"; 133 static class X 134 { 135 string phrase() 136 { 137 return null; 138 } 139 } 140 Mocker mocker; 141 auto builder = mocker.stub!X; 142 143 builder.stub.phrase.returns(leibniz); 144 builder.stub.phrase.returns(schopenhauer); 145 146 builder.get.phrase.should.equal(schopenhauer); 147 } 148 149 @("overrides default stub") 150 unittest 151 { 152 static class Dependency 153 { 154 string translate(string) 155 { 156 assert(false); 157 } 158 } 159 Mocker mocker; 160 auto builder = mocker.stub!Dependency; 161 162 builder.stub.translate!string.returns("im Sinne"); 163 builder.stub.translate!string.returns("in mente"); 164 165 builder.get.translate("latin").should.equal("in mente"); 166 } 167 168 @("checks whether arguments were set when overriding") 169 unittest 170 { 171 static class Dependency 172 { 173 string translate(string language) 174 { 175 return language == "latin" ? "in mente" : null; 176 } 177 } 178 Mocker mocker; 179 auto builder = mocker.stub!Dependency; 180 181 builder.stub.translate!string.returns("im Sinne"); 182 builder.stub.translate("latin").returns("in mente"); 183 184 builder.get.translate("latin").should.equal("in mente"); 185 } 186 187 @ShouldFail("throws if nothing matches") 188 unittest 189 { 190 static class Dependency 191 { 192 string translate() 193 { 194 return "quinta essentia"; 195 } 196 } 197 Mocker mocker; 198 auto builder = mocker.stub!Dependency; 199 200 builder.get.translate.should.be(null); 201 }